#include "asterisk.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <regex.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/compiler.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"
Include dependency graph for chan_sip.c:
Go to the source code of this file.
Data Structures | |
struct | ast_peer_list |
The peer list: Peers and Friends. More... | |
struct | ast_register_list |
The register list: Other SIP proxys we register with and place calls to. More... | |
struct | ast_user_list |
The user list: Users and friends. More... | |
struct | c_referstatusstring |
struct | cfsip_methods |
struct | cfsip_options |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More... | |
struct | cfsubscription_types |
struct | domain |
Domain data structure. More... | |
struct | sip_auth |
sip_auth: Credentials for authentication to other SIP services More... | |
struct | sip_dual |
structure used in transfers More... | |
struct | sip_history |
sip_history: Structure for saving transactions within a SIP dialog More... | |
struct | sip_invite_param |
Parameters to the transmit_invite function. More... | |
struct | sip_peer |
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host). More... | |
struct | sip_pkt |
sip packet - raw format for outbound packets that are sent or scheduled for transmission More... | |
struct | sip_pvt |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe More... | |
struct | sip_refer |
Structure to handle SIP transfers. Dynamically allocated when needed. More... | |
struct | sip_registry |
Registrations with other SIP proxies. More... | |
struct | sip_request |
sip_request: The data grabbed from the UDP socket More... | |
struct | sip_route |
Structure to save routing information for a SIP session. More... | |
struct | sip_user |
Structure for SIP user data. User's place calls to us. More... | |
struct | t38properties |
T.38 channel settings (at some point we need to make this alloc'ed. More... | |
Defines | |
#define | ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
SIP Methods we support. | |
#define | append_history(p, event, fmt, args...) append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history. | |
#define | CALLERID_UNKNOWN "Unknown" |
#define | CAN_CREATE_DIALOG 1 |
#define | CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
#define | CAN_NOT_CREATE_DIALOG 0 |
#define | DEC_CALL_LIMIT 0 |
#define | DEC_CALL_RINGING 2 |
#define | DEFAULT_ALLOW_EXT_DOM TRUE |
#define | DEFAULT_ALLOWGUEST TRUE |
#define | DEFAULT_AUTOCREATEPEER FALSE |
#define | DEFAULT_CALLERID "asterisk" |
#define | DEFAULT_COMPACTHEADERS FALSE |
#define | DEFAULT_CONTEXT "default" |
#define | DEFAULT_DEFAULT_EXPIRY 120 |
#define | DEFAULT_EXPIRY 900 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_CALL_BITRATE (384) |
#define | DEFAULT_MAX_EXPIRY 3600 |
#define | DEFAULT_MAX_FORWARDS "70" |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_MIN_EXPIRY 60 |
#define | DEFAULT_MOHINTERPRET "default" |
#define | DEFAULT_MOHSUGGEST "" |
#define | DEFAULT_MWITIME 10 |
#define | DEFAULT_NOTIFYMIME "application/simple-message-summary" |
#define | DEFAULT_NOTIFYRINGING TRUE |
#define | DEFAULT_PEDANTIC FALSE |
#define | DEFAULT_QUALIFY FALSE |
#define | DEFAULT_REALM "asterisk" |
#define | DEFAULT_REGISTRATION_TIMEOUT 20 |
#define | DEFAULT_RETRANS 1000 |
#define | DEFAULT_SRVLOOKUP FALSE |
#define | DEFAULT_T1MIN 100 |
#define | DEFAULT_TOS_AUDIO 0 |
#define | DEFAULT_TOS_SIP 0 |
#define | DEFAULT_TOS_VIDEO 0 |
#define | DEFAULT_TRANS_TIMEOUT -1 |
#define | DEFAULT_USERAGENT "Asterisk PBX" |
#define | DEFAULT_VMEXTEN "asterisk" |
#define | EXPIRY_GUARD_LIMIT 30 |
#define | EXPIRY_GUARD_MIN 500 |
#define | EXPIRY_GUARD_PCT 0.20 |
#define | EXPIRY_GUARD_SECS 15 |
#define | FALSE 0 |
#define | FLAG_FATAL (1 << 1) |
#define | FLAG_RESPONSE (1 << 0) |
#define | FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s %-10.10s\n" |
#define | FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" |
#define | FORMAT "%-40.40s %-20.20s %-16.16s\n" |
#define | FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-4.4s %-7.7s %-15.15s\n" |
#define | FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" |
#define | INC_CALL_LIMIT 1 |
#define | INC_CALL_RINGING 3 |
#define | INITIAL_CSEQ 101 |
#define | IPTOS_MINCOST 0x02 |
#define | MAX(a, b) ((a) > (b) ? (a) : (b)) |
#define | MAX_AUTHTRIES 3 |
#define | MAX_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 |
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 } |
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 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) |
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_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. | |
static int | transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
Transmit SIP request, auth added. | |
static int | transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Transmit response, no retransmits. | |
static int | transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK. | |
static int | transmit_response_using_temp (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg) |
Transmit response, no retransmits, using a temporary pvt structure. | |
static int | transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Append Accept header, content length before transmitting response. | |
static int | transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale) |
Respond with authorization request. | |
static int | transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Append date and content length before transmitting response. | |
static int | transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Used for 200 OK and 183 early media. | |
static int | transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans) |
Used for 200 OK and 183 early media. | |
static int | transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported) |
Transmit response, no retransmits. | |
static int | transmit_sip_request (struct sip_pvt *p, struct sip_request *req) |
Transmit SIP request unreliably (only used in sip_notify subsystem). | |
static int | transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout) |
Used in the SUBSCRIBE notification subsystem. | |
static void | try_suggested_sip_codec (struct sip_pvt *p) |
Try setting codec suggested by the SIP_CODEC channel variable. | |
static int | unload_module (void) |
PBX unload module API. | |
static int | update_call_counter (struct sip_pvt *fup, int event) |
update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted. | |
static void | update_peer (struct sip_peer *p, int expiry) |
Update peer data in database (if used). | |
Variables | |
static struct in_addr | __ourip |
static int | allow_external_domains |
static int | apeerobjs = 0 |
static char * | app_dtmfmode = "SIPDtmfMode" |
static char * | app_sipaddheader = "SIPAddHeader" |
static struct sip_auth * | authl = NULL |
static int | autocreatepeer |
static struct sockaddr_in | bindaddr = { 0, } |
static struct ast_custom_function | checksipdomain_function |
static struct ast_cli_entry | cli_sip [] |
static struct ast_cli_entry | cli_sip_debug_deprecated |
static struct ast_cli_entry | cli_sip_no_debug_deprecated |
static int | compactheaders |
static const char | config [] = "sip.conf" |
static char | debug_usage [] |
static struct sockaddr_in | debugaddr |
static char | default_callerid [AST_MAX_EXTENSION] |
static char | default_context [AST_MAX_CONTEXT] |
static int | default_expiry = DEFAULT_DEFAULT_EXPIRY |
static char | default_fromdomain [AST_MAX_EXTENSION] |
static struct ast_jb_conf | default_jbconf |
Global jitterbuffer configuration - by default, jb is disabled. | |
static char | default_language [MAX_LANGUAGE] |
static int | default_maxcallbitrate |
static char | default_mohinterpret [MAX_MUSICCLASS] |
static char | default_mohsuggest [MAX_MUSICCLASS] |
static char | default_notifymime [AST_MAX_EXTENSION] |
static struct ast_codec_pref | default_prefs |
static int | default_qualify |
static char | default_subscribecontext [AST_MAX_CONTEXT] |
static char | default_vmexten [AST_MAX_EXTENSION] |
static char * | descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" |
static char * | descrip_sipaddheader |
static int | dumphistory |
static int | expiry = DEFAULT_EXPIRY |
static time_t | externexpire = 0 |
static char | externhost [MAXHOSTNAMELEN] |
static struct sockaddr_in | externip |
static int | externrefresh = 10 |
static int | global_allowguest |
static int | global_allowsubscribe |
static enum transfermodes | global_allowtransfer |
static int | global_alwaysauthreject |
static int | global_autoframing |
static int | global_callevents |
static int | global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 |
Codecs that we support by default:. | |
static int | global_directrtpsetup |
static struct ast_flags | global_flags [2] = {{0}} |
static struct ast_jb_conf | global_jbconf |
static int | global_limitonpeers |
static int | global_matchexterniplocally |
static int | global_mwitime |
static int | global_notifyhold |
static int | global_notifyringing |
static char | global_realm [MAXHOSTNAMELEN] |
static int | global_reg_timeout |
static int | global_regattempts_max |
static char | global_regcontext [AST_MAX_CONTEXT] |
static int | global_relaxdtmf |
static int | global_rtautoclear |
static int | global_rtpholdtimeout |
static int | global_rtpkeepalive |
static int | global_rtptimeout |
static int | global_t1min |
static int | global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 |
static unsigned int | global_tos_audio |
static unsigned int | global_tos_sip |
static unsigned int | global_tos_video |
static char | global_useragent [AST_MAX_EXTENSION] |
static char | history_usage [] |
static struct sip_pvt * | iflist |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe | |
static struct io_context * | io |
static struct ast_ha * | localaddr |
static char | mandescr_show_peer [] |
static char | mandescr_show_peers [] |
static int | max_expiry = DEFAULT_MAX_EXPIRY |
static int | min_expiry = DEFAULT_MIN_EXPIRY |
static pthread_t | monitor_thread = AST_PTHREADT_NULL |
This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
static char | no_debug_usage [] |
static char | no_history_usage [] |
static const char | notify_config [] = "sip_notify.conf" |
static struct ast_config * | notify_types |
static char | notify_usage [] |
static int | ourport |
static struct sockaddr_in | outboundproxyip |
static int | pedanticsipchecking |
static struct ast_peer_list | peerl |
The peer list: Peers and Friends. | |
static char | prune_realtime_usage [] |
static int | recordhistory |
static struct c_referstatusstring | referstatusstrings [] |
static struct ast_register_list | regl |
The register list: Other SIP proxys we register with and place calls to. | |
static int | regobjs = 0 |
static int | rpeerobjs = 0 |
static int | ruserobjs = 0 |
static struct sched_context * | sched |
static char | show_channel_usage [] |
static char | show_channels_usage [] |
static char | show_domains_usage [] |
static char | show_history_usage [] |
static char | show_inuse_usage [] |
static char | show_objects_usage [] |
static char | show_peer_usage [] |
static char | show_peers_usage [] |
static char | show_reg_usage [] |
static char | show_settings_usage [] |
static char | show_subscriptions_usage [] |
static char | show_user_usage [] |
static char | show_users_usage [] |
static struct ast_custom_function | sip_header_function |
static struct cfsip_methods | sip_methods [] |
static struct cfsip_options | sip_options [] |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. | |
static char | sip_reload_usage [] |
static int | sip_reloading = FALSE |
static enum channelreloadreason | sip_reloadreason |
static struct ast_rtp_protocol | sip_rtp |
Interface structure with callbacks used to connect to RTP module. | |
static struct ast_channel_tech | sip_tech |
Definition of this channel for PBX channel registration. | |
static struct ast_channel_tech | sip_tech_info |
This version of the sip channel tech has no send_digit_begin callback. This is for use with channels using SIP INFO DTMF so that the core knows that the channel doesn't want DTMF BEGIN frames. | |
static struct ast_udptl_protocol | sip_udptl |
Interface structure with callbacks used to connect to UDPTL module. | |
static struct ast_custom_function | sipchaninfo_function |
Structure to declare a dialplan function: SIPCHANINFO. | |
ast_custom_function | sippeer_function |
Structure to declare a dialplan function: SIPPEER. | |
static int | sipsock = -1 |
static int * | sipsock_read_id |
static int | speerobjs = 0 |
static int | srvlookup |
static struct cfsubscription_types | subscription_types [] |
static int | suserobjs = 0 |
static char * | synopsis_dtmfmode = "Change the dtmfmode for a SIP call" |
static char * | synopsis_sipaddheader = "Add a SIP header to the outbound call" |
static struct ast_user_list | userl |
The user list: Users and friends. |
See Also: Implementation of RFC 3261 - without S/MIME, TCP and TLS support Configuration file sip.conf
A new INVITE is sent to handle_request_invite(), that will end up starting a new channel in the PBX, the new channel after that executing in a separate channel thread. This is an incoming "call". When the call is answered, either by a bridged channel or the PBX itself the sip_answer() function is called.
The actual media - Video or Audio - is mostly handled by the RTP subsystem in rtp.c
Definition in file chan_sip.c.
#define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
SIP Methods we support.
Definition at line 464 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 1811 of file chan_sip.c.
Referenced by __sip_autodestruct(), auto_congest(), build_reply_digest(), cb_extensionstate(), 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(), local_attended_transfer(), process_sdp(), retrans_pkt(), send_request(), send_response(), sip_cancel_destroy(), sip_fixup(), sip_hangup(), sip_new(), sip_park_thread(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), sipsock_read(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_with_auth().
#define CALLERID_UNKNOWN "Unknown" |
#define CAN_CREATE_DIALOG 1 |
Definition at line 357 of file chan_sip.c.
#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
Definition at line 358 of file chan_sip.c.
#define CAN_NOT_CREATE_DIALOG 0 |
Definition at line 356 of file chan_sip.c.
#define DEC_CALL_LIMIT 0 |
Definition at line 597 of file chan_sip.c.
Referenced by __sip_destroy(), handle_request_invite(), handle_response_invite(), sip_hangup(), and update_call_counter().
#define DEC_CALL_RINGING 2 |
Definition at line 599 of file chan_sip.c.
Referenced by handle_response_invite(), and update_call_counter().
#define DEFAULT_ALLOW_EXT_DOM TRUE |
#define DEFAULT_ALLOWGUEST TRUE |
#define DEFAULT_AUTOCREATEPEER FALSE |
#define DEFAULT_CALLERID "asterisk" |
#define DEFAULT_COMPACTHEADERS FALSE |
#define DEFAULT_CONTEXT "default" |
#define DEFAULT_DEFAULT_EXPIRY 120 |
Definition at line 164 of file chan_sip.c.
#define DEFAULT_EXPIRY 900 |
Expire slowly
Definition at line 181 of file chan_sip.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Qualification: How often to check, if the host is down...
Definition at line 196 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 195 of file chan_sip.c.
#define DEFAULT_MAX_CALL_BITRATE (384) |
#define DEFAULT_MAX_EXPIRY 3600 |
Definition at line 166 of file chan_sip.c.
#define DEFAULT_MAX_FORWARDS "70" |
Definition at line 168 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 194 of file chan_sip.c.
#define DEFAULT_MIN_EXPIRY 60 |
Definition at line 165 of file chan_sip.c.
#define DEFAULT_MOHINTERPRET "default" |
#define DEFAULT_MOHSUGGEST "" |
#define DEFAULT_MWITIME 10 |
#define DEFAULT_NOTIFYMIME "application/simple-message-summary" |
#define DEFAULT_NOTIFYRINGING TRUE |
#define DEFAULT_PEDANTIC FALSE |
#define DEFAULT_QUALIFY FALSE |
#define DEFAULT_REALM "asterisk" |
#define DEFAULT_REGISTRATION_TIMEOUT 20 |
#define DEFAULT_RETRANS 1000 |
How frequently to retransmit Default: 2 * 500 ms in RFC 3261
Definition at line 198 of file chan_sip.c.
#define DEFAULT_SRVLOOKUP FALSE |
#define DEFAULT_T1MIN 100 |
100 MS for minimal roundtrip time
Definition at line 502 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 494 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 493 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 495 of file chan_sip.c.
Referenced by reload_config().
#define DEFAULT_TRANS_TIMEOUT -1 |
Definition at line 203 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 505 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 173 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 175 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 179 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 172 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 1007 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 598 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 210 of file chan_sip.c.
Referenced by sip_alloc(), sip_register(), and transmit_response_using_temp().
#define IPTOS_MINCOST 0x02 |
Definition at line 159 of file chan_sip.c.
#define MAX | ( | a, | |||
b | ) | ((a) > (b) ? (a) : (b)) |
Definition at line 189 of file chan_sip.c.
#define MAX_AUTHTRIES 3 |
Try authentication three times, then fail
Definition at line 204 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 199 of file chan_sip.c.
#define NO_RTP 0 |
Definition at line 226 of file chan_sip.c.
#define NOT_SUPPORTED 0 |
Definition at line 397 of file chan_sip.c.
#define RTP 1 |
Definition at line 225 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 704 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 745 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 733 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), reload_config(), sip_get_rtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), and sip_handle_t38_reinvite().
#define SIP_CAN_REINVITE_NAT (2 << 20) |
allow media reinvite when new peer is behind NAT
Definition at line 734 of file chan_sip.c.
Referenced by handle_common_options(), sip_get_rtp_peer(), and sip_set_rtp_peer().
#define SIP_DEFER_BYE_ON_TRANSFER (1 << 15) |
Do not hangup at first ast_hangup
Definition at line 719 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 720 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 724 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 722 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 723 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 721 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 750 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 718 of file chan_sip.c.
#define SIP_G726_NONSTANDARD (1 << 31) |
Use non-standard packing for G726-32 data
Definition at line 748 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 711 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 747 of file chan_sip.c.
Referenced by __sip_destroy(), sip_hangup(), and update_call_counter().
#define SIP_INSECURE_INVITE (1 << 24) |
don't require authentication for incoming INVITEs
Definition at line 738 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), and handle_common_options().
#define SIP_INSECURE_PORT (1 << 23) |
don't require matching port for incoming requests
Definition at line 737 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), and sip_addrcmp().
#define SIP_MAX_HEADERS 64 |
Max amount of SIP headers to read
Definition at line 206 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 207 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 208 of file chan_sip.c.
#define SIP_NAT (3 << 18) |
four settings, uses two bits
Definition at line 726 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 730 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 727 of file chan_sip.c.
Referenced by handle_common_options(), and nat2str().
#define SIP_NAT_RFC3581 (1 << 18) |
NAT RFC3581
Definition at line 728 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 729 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 705 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 709 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 744 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 706 of file chan_sip.c.
Referenced by add_sdp(), process_sdp(), and sip_indicate().
#define SIP_OPT_100REL (1 << 1) |
Definition at line 400 of file chan_sip.c.
#define SIP_OPT_EARLY_SESSION (1 << 3) |
Definition at line 402 of file chan_sip.c.
#define SIP_OPT_EVENTLIST (1 << 11) |
Definition at line 410 of file chan_sip.c.
#define SIP_OPT_GRUU (1 << 12) |
Definition at line 411 of file chan_sip.c.
#define SIP_OPT_HISTINFO (1 << 15) |
Definition at line 414 of file chan_sip.c.
#define SIP_OPT_JOIN (1 << 4) |
Definition at line 403 of file chan_sip.c.
#define SIP_OPT_NOREFERSUB (1 << 14) |
Definition at line 413 of file chan_sip.c.
#define SIP_OPT_PATH (1 << 5) |
Definition at line 404 of file chan_sip.c.
#define SIP_OPT_PRECONDITION (1 << 7) |
Definition at line 406 of file chan_sip.c.
#define SIP_OPT_PREF (1 << 6) |
Definition at line 405 of file chan_sip.c.
#define SIP_OPT_PRIVACY (1 << 8) |
Definition at line 407 of file chan_sip.c.
#define SIP_OPT_REPLACES (1 << 0) |
#define SIP_OPT_RESPRIORITY (1 << 16) |
Definition at line 415 of file chan_sip.c.
#define SIP_OPT_SDP_ANAT (1 << 9) |
Definition at line 408 of file chan_sip.c.
#define SIP_OPT_SEC_AGREE (1 << 10) |
Definition at line 409 of file chan_sip.c.
#define SIP_OPT_TARGET_DIALOG (1 << 13) |
Definition at line 412 of file chan_sip.c.
#define SIP_OPT_TIMER (1 << 2) |
Definition at line 401 of file chan_sip.c.
#define SIP_OUTGOING (1 << 13) |
Direction of the last transaction in this dialog
Definition at line 717 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 771 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 770 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), handle_common_options(), handle_request_subscribe(), reload_config(), and sip_show_settings().
#define SIP_PAGE2_BUGGY_MWI (1 << 26) |
26: Buggy CISCO MWI fix
Definition at line 783 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 778 of file chan_sip.c.
Referenced by __sip_show_channels(), add_sdp(), process_sdp(), 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 781 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp().
#define SIP_PAGE2_CALL_ONHOLD_ONEDIR (2 << 23) |
23: One directional hold
Definition at line 780 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp().
#define SIP_PAGE2_DEBUG (3 << 11) |
Definition at line 764 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
#define SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
Definition at line 766 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 767 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 786 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 763 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), and sip_show_settings().
#define SIP_PAGE2_INC_RINGING (1 << 19) |
Did this connection increment the counter of in-use calls?
Definition at line 773 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 784 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 782 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 760 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), parse_register_contact(), and reg_source_db().
#define SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
#define SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
Definition at line 757 of file chan_sip.c.
Referenced by complete_sip_prune_realtime_peer(), complete_sip_prune_realtime_user(), sip_prune_realtime(), sip_show_settings(), and update_peer().
#define SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
Definition at line 761 of file chan_sip.c.
Referenced by realtime_update_peer(), and sip_show_settings().
#define SIP_PAGE2_RTUPDATE (1 << 1) |
Definition at line 758 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 768 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 772 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 774 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 776 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 777 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 775 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 769 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 710 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 791 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 793 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 792 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 740 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 742 of file chan_sip.c.
Referenced by handle_common_options(), and sip_show_settings().
#define SIP_PROG_INBAND_YES (2 << 25) |
Definition at line 743 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 708 of file chan_sip.c.
Referenced by sip_indicate(), and sip_write().
#define SIP_PROMISCREDIR (1 << 8) |
Promiscuous redirection
Definition at line 712 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 715 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), parse_register_contact(), sip_destroy_peer(), sip_destroy_user(), and update_peer().
#define SIP_REINVITE (7 << 20) |
#define SIP_REINVITE_UPDATE (4 << 20) |
use UPDATE (RFC3311) when reinviting this peer
Definition at line 735 of file chan_sip.c.
Referenced by handle_common_options(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
#define SIP_RINGING (1 << 3) |
#define SIP_SENDRPID (1 << 29) |
Remote Party-ID Support
Definition at line 746 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 200 of file chan_sip.c.
Referenced by sip_call().
#define SIP_TRUSTRPID (1 << 9) |
Trust RPID headers?
Definition at line 713 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 716 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 714 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), initreqprep(), and sip_show_settings().
#define sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG) |
Definition at line 823 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 824 of file chan_sip.c.
#define sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
Definition at line 825 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 470 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 396 of file chan_sip.c.
#define SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support.
Definition at line 467 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 798 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 817 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 818 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 813 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 814 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 815 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 816 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 803 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
Definition at line 802 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 800 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 799 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 806 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 805 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 807 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 809 of file chan_sip.c.
Referenced by add_t38_sdp().
#define T38FAX_VERSION_0 (0 << 6) |
Version 0
Definition at line 810 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_VERSION_1 (1 << 6) |
Version 1
Definition at line 811 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 1581 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 157 of file chan_sip.c.
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 |
Definition at line 334 of file chan_sip.c.
00334 { 00335 AUTH_SUCCESSFUL = 0, 00336 AUTH_CHALLENGE_SENT = 1, 00337 AUTH_SECRET_FAILED = -1, 00338 AUTH_USERNAME_MISMATCH = -2, 00339 AUTH_NOT_FOUND = -3, 00340 AUTH_FAKE_AUTH = -4, 00341 AUTH_UNKNOWN_DOMAIN = -5, 00342 };
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 667 of file chan_sip.c.
00667 { 00668 SIP_DOMAIN_AUTO, /*!< This domain is auto-configured */ 00669 SIP_DOMAIN_CONFIG, /*!< This domain is from configuration */ 00670 };
enum invitestates |
States for the INVITE transaction, not the dialog.
Definition at line 245 of file chan_sip.c.
00245 { 00246 INV_NONE = 0, /*!< No state at all, maybe not an INVITE dialog */ 00247 INV_CALLING = 1, /*!< Invite sent, no answer */ 00248 INV_PROCEEDING = 2, /*!< We got/sent 1xx message */ 00249 INV_EARLY_MEDIA = 3, /*!< We got 18x message with to-tag back */ 00250 INV_COMPLETED = 4, /*!< Got final response with error. Wait for ACK, then CONFIRMED */ 00251 INV_CONFIRMED = 5, /*!< Confirmed response - we've got an ack (Incoming calls only) */ 00252 INV_TERMINATED = 6, /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done 00253 The only way out of this is a BYE from one side */ 00254 INV_CANCELLED = 7, /*!< Transaction cancelled by client or server in non-terminated state */ 00255 };
Definition at line 272 of file chan_sip.c.
00272 { 00273 PARSE_REGISTER_FAILED, 00274 PARSE_REGISTER_UPDATE, 00275 PARSE_REGISTER_QUERY, 00276 };
enum referstatus |
Parameters to know status of transfer.
Definition at line 847 of file chan_sip.c.
00847 { 00848 REFER_IDLE, /*!< No REFER is in progress */ 00849 REFER_SENT, /*!< Sent REFER to transferee */ 00850 REFER_RECEIVED, /*!< Received REFER from transferer */ 00851 REFER_CONFIRMED, /*!< Refer confirmed with a 100 TRYING */ 00852 REFER_ACCEPTED, /*!< Accepted by transferee */ 00853 REFER_RINGING, /*!< Target Ringing */ 00854 REFER_200OK, /*!< Answered by transfer target */ 00855 REFER_FAILED, /*!< REFER declined - go on */ 00856 REFER_NOAUTH /*!< We had no auth for REFER */ 00857 };
enum sip_auth_type |
Authentication types - proxy or www authentication.
Definition at line 328 of file chan_sip.c.
00328 { 00329 PROXY_AUTH, 00330 WWW_AUTH, 00331 };
enum sip_result |
Definition at line 237 of file chan_sip.c.
00237 { 00238 AST_SUCCESS = 0, 00239 AST_FAILURE = -1, 00240 };
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 303 of file chan_sip.c.
00303 { 00304 SIP_UNKNOWN, /* Unknown response */ 00305 SIP_RESPONSE, /* Not request, response to outbound request */ 00306 SIP_REGISTER, 00307 SIP_OPTIONS, 00308 SIP_NOTIFY, 00309 SIP_INVITE, 00310 SIP_ACK, 00311 SIP_PRACK, /* Not supported at all */ 00312 SIP_BYE, 00313 SIP_REFER, 00314 SIP_SUBSCRIBE, 00315 SIP_MESSAGE, 00316 SIP_UPDATE, /* We can send UPDATE; but not accept it */ 00317 SIP_INFO, 00318 SIP_CANCEL, 00319 SIP_PUBLISH, /* Not supported at all */ 00320 SIP_PING, /* Not supported at all, no standard but still implemented out there */ 00321 };
enum sipregistrystate |
States for outbound registrations (with register= lines in sip.conf.
Definition at line 345 of file chan_sip.c.
00345 { 00346 REG_STATE_UNREGISTERED = 0, /*!< We are not registred */ 00347 REG_STATE_REGSENT, /*!< Registration request sent */ 00348 REG_STATE_AUTHSENT, /*!< We have tried to authenticate */ 00349 REG_STATE_REGISTERED, /*!< Registred and done */ 00350 REG_STATE_REJECTED, /*!< Registration rejected */ 00351 REG_STATE_TIMEOUT, /*!< Registration timed out */ 00352 REG_STATE_NOAUTH, /*!< We have no accepted credentials */ 00353 REG_STATE_FAILED, /*!< Registration failed after several tries */ 00354 };
enum subscriptiontype |
Definition at line 278 of file chan_sip.c.
00278 { 00279 NONE = 0, 00280 XPIDF_XML, 00281 DIALOG_INFO_XML, 00282 CPIM_PIDF_XML, 00283 PIDF_XML, 00284 MWI_NOTIFICATION 00285 };
enum t38state |
T38 States for a call.
Definition at line 828 of file chan_sip.c.
00828 { 00829 T38_DISABLED = 0, /*!< Not enabled */ 00830 T38_LOCAL_DIRECT, /*!< Offered from local */ 00831 T38_LOCAL_REINVITE, /*!< Offered from local - REINVITE */ 00832 T38_PEER_DIRECT, /*!< Offered from peer */ 00833 T38_PEER_REINVITE, /*!< Offered from peer - REINVITE */ 00834 T38_ENABLED /*!< Negotiated (enabled) */ 00835 };
enum transfermodes |
Authorization scheme for call transfers.
Definition at line 231 of file chan_sip.c.
00231 { 00232 TRANSFER_OPENFORALL, /*!< Allow all SIP transfers */ 00233 TRANSFER_CLOSED, /*!< Allow no SIP transfers */ 00234 };
enum xmittype |
Definition at line 265 of file chan_sip.c.
00265 { 00266 XMIT_CRITICAL = 2, /*!< Transmit critical SIP message reliably, with re-transmits. 00267 If it fails, it's critical and will cause a teardown of the session */ 00268 XMIT_RELIABLE = 1, /*!< Transmit SIP message reliably, with re-transmits */ 00269 XMIT_UNRELIABLE = 0, /*!< Transmit SIP message without bothering with re-transmits */ 00270 };
static const char * __get_header | ( | const struct sip_request * | req, | |
const char * | name, | |||
int * | start | |||
) | [static] |
Definition at line 4007 of file chan_sip.c.
References find_alias(), sip_request::header, sip_request::headers, and len.
04008 { 04009 int pass; 04010 04011 /* 04012 * Technically you can place arbitrary whitespace both before and after the ':' in 04013 * a header, although RFC3261 clearly says you shouldn't before, and place just 04014 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 04015 * a good idea to say you can do it, and if you can do it, why in the hell would. 04016 * you say you shouldn't. 04017 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 04018 * and we always allow spaces after that for compatibility. 04019 */ 04020 for (pass = 0; name && pass < 2;pass++) { 04021 int x, len = strlen(name); 04022 for (x=*start; x<req->headers; x++) { 04023 if (!strncasecmp(req->header[x], name, len)) { 04024 char *r = req->header[x] + len; /* skip name */ 04025 if (pedanticsipchecking) 04026 r = ast_skip_blanks(r); 04027 04028 if (*r == ':') { 04029 *start = x+1; 04030 return ast_skip_blanks(r+1); 04031 } 04032 } 04033 } 04034 if (pass == 0) /* Try aliases */ 04035 name = find_alias(name, NULL); 04036 } 04037 04038 /* Don't return NULL, so get_header is always a valid pointer */ 04039 return ""; 04040 }
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 2056 of file chan_sip.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_test_flag, sip_pkt::data, FALSE, FLAG_RESPONSE, free, sip_pvt::lock, LOG_DEBUG, sip_pkt::next, option_debug, sip_pvt::packets, sip_pvt::pendinginvite, sip_pkt::retransid, sched, sip_pkt::seqno, sip_methods, sipdebug, cfsip_methods::text, TRUE, and UNLINK.
Referenced by __sip_pretend_ack(), handle_request(), and handle_response().
02057 { 02058 struct sip_pkt *cur, *prev = NULL; 02059 02060 /* Just in case... */ 02061 char *msg; 02062 int res = FALSE; 02063 02064 msg = sip_methods[sipmethod].text; 02065 02066 ast_mutex_lock(&p->lock); 02067 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 02068 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 02069 ((ast_test_flag(cur, FLAG_RESPONSE)) || 02070 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 02071 if (!resp && (seqno == p->pendinginvite)) { 02072 if (option_debug) 02073 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 02074 p->pendinginvite = 0; 02075 } 02076 /* this is our baby */ 02077 res = TRUE; 02078 UNLINK(cur, p->packets, prev); 02079 if (cur->retransid > -1) { 02080 if (sipdebug && option_debug > 3) 02081 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 02082 ast_sched_del(sched, cur->retransid); 02083 cur->retransid = -1; 02084 } 02085 free(cur); 02086 break; 02087 } 02088 } 02089 ast_mutex_unlock(&p->lock); 02090 if (option_debug) 02091 ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found"); 02092 }
static int __sip_autodestruct | ( | void * | data | ) | [static] |
Kill a SIP dialog (called by scheduler).
Definition at line 1990 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup(), ASTOBJ_UNREF, sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, LOG_DEBUG, LOG_WARNING, sip_pvt::method, NONE, option_debug, sip_pvt::owner, sip_pvt::refer, sip_pvt::relatedpeer, SIP_BYE, sip_destroy(), sip_destroy_peer(), sip_methods, sip_scheddestroy(), sip_pvt::subscribed, cfsip_methods::text, transmit_request_with_auth(), transmit_state_notify(), TRUE, and XMIT_RELIABLE.
Referenced by sip_scheddestroy().
01991 { 01992 struct sip_pvt *p = data; 01993 01994 /* If this is a subscription, tell the phone that we got a timeout */ 01995 if (p->subscribed) { 01996 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 01997 p->subscribed = NONE; 01998 append_history(p, "Subscribestatus", "timeout"); 01999 if (option_debug > 2) 02000 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>"); 02001 return 10000; /* Reschedule this destruction so that we know that it's gone */ 02002 } 02003 02004 /* If we're destroying a subscription, dereference peer object too */ 02005 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 02006 ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer); 02007 02008 /* Reset schedule ID */ 02009 p->autokillid = -1; 02010 02011 if (option_debug) 02012 ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid); 02013 append_history(p, "AutoDestroy", "%s", p->callid); 02014 if (p->owner) { 02015 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 02016 ast_queue_hangup(p->owner); 02017 } else if (p->refer) { 02018 if (option_debug > 2) 02019 ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid); 02020 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 02021 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 02022 } else 02023 sip_destroy(p); 02024 return 0; 02025 }
static void __sip_destroy | ( | struct sip_pvt * | p, | |
int | lockowner | |||
) | [static] |
Execute destruction of SIP dialog structure, release memory.
Definition at line 2885 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_extension_state_del(), AST_LIST_REMOVE_HEAD, ast_log(), ast_rtp_destroy(), ast_sched_del(), ast_test_flag, ast_udptl_destroy(), ast_verbose(), ASTOBJ_UNREF, DEC_CALL_LIMIT, sip_pvt::flags, free, free_old_route(), iflist, LOG_DEBUG, LOG_WARNING, sip_pvt::method, sip_peer::mwipvt, sip_pvt::next, option_debug, sip_pvt::relatedpeer, sip_pkt::retransid, sched, sip_debug_test_pvt(), sip_dump_history(), SIP_INC_COUNT, sip_methods, sip_registry_destroy(), cfsip_methods::text, UNLINK, and update_call_counter().
Referenced by do_monitor(), sip_destroy(), and unload_module().
02886 { 02887 struct sip_pvt *cur, *prev = NULL; 02888 struct sip_pkt *cp; 02889 02890 if (sip_debug_test_pvt(p) || option_debug > 2) 02891 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 02892 02893 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT)) { 02894 update_call_counter(p, DEC_CALL_LIMIT); 02895 if (option_debug > 1) 02896 ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 02897 } 02898 02899 /* Remove link from peer to subscription of MWI */ 02900 if (p->relatedpeer && p->relatedpeer->mwipvt) 02901 p->relatedpeer->mwipvt = NULL; 02902 02903 if (dumphistory) 02904 sip_dump_history(p); 02905 02906 if (p->options) 02907 free(p->options); 02908 02909 if (p->stateid > -1) 02910 ast_extension_state_del(p->stateid, NULL); 02911 if (p->initid > -1) 02912 ast_sched_del(sched, p->initid); 02913 if (p->autokillid > -1) 02914 ast_sched_del(sched, p->autokillid); 02915 02916 if (p->rtp) 02917 ast_rtp_destroy(p->rtp); 02918 if (p->vrtp) 02919 ast_rtp_destroy(p->vrtp); 02920 if (p->udptl) 02921 ast_udptl_destroy(p->udptl); 02922 if (p->refer) 02923 free(p->refer); 02924 if (p->route) { 02925 free_old_route(p->route); 02926 p->route = NULL; 02927 } 02928 if (p->registry) { 02929 if (p->registry->call == p) 02930 p->registry->call = NULL; 02931 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 02932 } 02933 02934 /* Unlink us from the owner if we have one */ 02935 if (p->owner) { 02936 if (lockowner) 02937 ast_channel_lock(p->owner); 02938 if (option_debug) 02939 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 02940 p->owner->tech_pvt = NULL; 02941 if (lockowner) 02942 ast_channel_unlock(p->owner); 02943 } 02944 /* Clear history */ 02945 if (p->history) { 02946 struct sip_history *hist; 02947 while( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) 02948 free(hist); 02949 free(p->history); 02950 p->history = NULL; 02951 } 02952 02953 for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) { 02954 if (cur == p) { 02955 UNLINK(cur, iflist, prev); 02956 break; 02957 } 02958 } 02959 if (!cur) { 02960 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 02961 return; 02962 } 02963 02964 /* remove all current packets in this dialog */ 02965 while((cp = p->packets)) { 02966 p->packets = p->packets->next; 02967 if (cp->retransid > -1) 02968 ast_sched_del(sched, cp->retransid); 02969 free(cp); 02970 } 02971 if (p->chanvars) { 02972 ast_variables_destroy(p->chanvars); 02973 p->chanvars = NULL; 02974 } 02975 ast_mutex_destroy(&p->lock); 02976 02977 ast_string_field_free_pools(p); 02978 02979 free(p); 02980 }
static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 7170 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
07171 { 07172 int res; 07173 07174 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 07175 return res; 07176 }
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 2096 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().
02097 { 02098 struct sip_pkt *cur = NULL; 02099 02100 while (p->packets) { 02101 int method; 02102 if (cur == p->packets) { 02103 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 02104 return; 02105 } 02106 cur = p->packets; 02107 method = (cur->method) ? cur->method : find_sip_method(cur->data); 02108 __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method); 02109 } 02110 }
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 1952 of file chan_sip.c.
References __sip_xmit(), ast_calloc, AST_FAILURE, ast_log(), ast_sched_add_variable(), ast_set_flag, AST_SUCCESS, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, LOG_DEBUG, option_debug, sip_pkt::owner, sip_pvt::packets, sip_pvt::pendinginvite, retrans_pkt(), sched, SIP_INVITE, sipdebug, and sip_pvt::timer_t1.
Referenced by send_request(), and send_response().
01953 { 01954 struct sip_pkt *pkt; 01955 int siptimer_a = DEFAULT_RETRANS; 01956 01957 if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) 01958 return AST_FAILURE; 01959 memcpy(pkt->data, data, len); 01960 pkt->method = sipmethod; 01961 pkt->packetlen = len; 01962 pkt->next = p->packets; 01963 pkt->owner = p; 01964 pkt->seqno = seqno; 01965 if (resp) 01966 ast_set_flag(pkt, FLAG_RESPONSE); 01967 pkt->data[len] = '\0'; 01968 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 01969 if (fatal) 01970 ast_set_flag(pkt, FLAG_FATAL); 01971 if (pkt->timer_t1) 01972 siptimer_a = pkt->timer_t1 * 2; 01973 01974 /* Schedule retransmission */ 01975 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 01976 if (option_debug > 3 && sipdebug) 01977 ast_log(LOG_DEBUG, "*** SIP TIMER: Initalizing retransmit timer on packet: Id #%d\n", pkt->retransid); 01978 pkt->next = p->packets; 01979 p->packets = pkt; 01980 01981 __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 01982 if (sipmethod == SIP_INVITE) { 01983 /* Note this is a pending invite */ 01984 p->pendinginvite = seqno; 01985 } 01986 return AST_SUCCESS; 01987 }
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 2113 of file chan_sip.c.
References ast_log(), ast_sched_del(), ast_test_flag, sip_pkt::data, FLAG_RESPONSE, LOG_DEBUG, method_match(), sip_pkt::next, option_debug, sip_pvt::packets, sip_pkt::retransid, sched, sip_pkt::seqno, sip_methods, sipdebug, and cfsip_methods::text.
Referenced by handle_response().
02114 { 02115 struct sip_pkt *cur; 02116 int res = -1; 02117 02118 for (cur = p->packets; cur; cur = cur->next) { 02119 if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp && 02120 (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) { 02121 /* this is our baby */ 02122 if (cur->retransid > -1) { 02123 if (option_debug > 3 && sipdebug) 02124 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 02125 ast_sched_del(sched, cur->retransid); 02126 cur->retransid = -1; 02127 } 02128 res = 0; 02129 break; 02130 } 02131 } 02132 if (option_debug) 02133 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"); 02134 return res; 02135 }
static int __sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[], | |||
int | subscriptions | |||
) | [static] |
SIP show channels CLI (main function).
Definition at line 10452 of file chan_sip.c.
References ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_test_flag, sip_pvt::flags, FORMAT, FORMAT2, FORMAT3, sip_pvt::icseq, iflist, sip_pvt::lastmsg, ast_channel::nativeformats, sip_pvt::next, NONE, sip_pvt::ocseq, sip_pvt::owner, sip_pvt::refer, referstatus2str(), RESULT_SHOWUSAGE, S_OR, sip_pvt::sa, SIP_NEEDDESTROY, SIP_PAGE2_CALL_ONHOLD, sip_refer::status, and sip_pvt::subscribed.
Referenced by sip_show_channels(), and sip_show_subscriptions().
10453 { 10454 #define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" 10455 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-4.4s %-7.7s %-15.15s\n" 10456 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s %-10.10s\n" 10457 struct sip_pvt *cur; 10458 int numchans = 0; 10459 char *referstatus = NULL; 10460 10461 if (argc != 3) 10462 return RESULT_SHOWUSAGE; 10463 ast_mutex_lock(&iflock); 10464 cur = iflist; 10465 if (!subscriptions) 10466 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 10467 else 10468 ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox"); 10469 for (; cur; cur = cur->next) { 10470 referstatus = ""; 10471 if (cur->refer) { /* SIP transfer in progress */ 10472 referstatus = referstatus2str(cur->refer->status); 10473 } 10474 if (cur->subscribed == NONE && !subscriptions) { 10475 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 10476 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10477 cur->callid, 10478 cur->ocseq, cur->icseq, 10479 ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), 10480 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 10481 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 10482 cur->lastmsg , 10483 referstatus 10484 ); 10485 numchans++; 10486 } 10487 if (cur->subscribed != NONE && subscriptions) { 10488 ast_cli(fd, FORMAT3, ast_inet_ntoa(cur->sa.sin_addr), 10489 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10490 cur->callid, 10491 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 10492 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 10493 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 10494 subscription_type2str(cur->subscribed), 10495 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>" 10496 ); 10497 numchans++; 10498 } 10499 } 10500 ast_mutex_unlock(&iflock); 10501 if (!subscriptions) 10502 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 10503 else 10504 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 10505 return RESULT_SUCCESS; 10506 #undef FORMAT 10507 #undef FORMAT2 10508 #undef FORMAT3 10509 }
static int __sip_xmit | ( | struct sip_pvt * | p, | |
char * | data, | |||
int | len | |||
) | [static] |
Transmit SIP message.
Definition at line 1748 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), LOG_WARNING, sip_real_dst(), and sipsock.
Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response().
01749 { 01750 int res; 01751 const struct sockaddr_in *dst = sip_real_dst(p); 01752 res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)); 01753 01754 if (res != len) 01755 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)); 01756 return res; 01757 }
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 5738 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().
05739 { 05740 struct sip_request resp; 05741 int seqno = 0; 05742 05743 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 05744 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 05745 return -1; 05746 } 05747 respprep(&resp, p, msg, req); 05748 add_header_contentLength(&resp, 0); 05749 /* If we are cancelling an incoming invite for some reason, add information 05750 about the reason why we are doing this in clear text */ 05751 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 05752 char buf[10]; 05753 05754 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 05755 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 05756 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 05757 } 05758 return send_response(p, &resp, reliable, seqno); 05759 }
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 10004 of file chan_sip.c.
References sip_peer::accountcode, sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_check_realtime(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_print_group(), ast_sched_when(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, dtmfmode2str(), sip_peer::expire, FALSE, find_peer(), sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, insecure2str(), sip_peer::language, sip_peer::lastmsg, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_auth::md5secret, sip_peer::md5secret, ast_variable::name, nat2str(), ast_variable::next, sip_auth::next, peer_status(), sip_peer::pickupgroup, sip_peer::prefs, print_codec_to_cli(), print_group(), sip_auth::realm, sip_peer::regexten, RESULT_SHOWUSAGE, RESULT_SUCCESS, s, S_OR, sched, sip_auth::secret, sip_peer::secret, SIP_CAN_REINVITE, sip_destroy_peer(), SIP_DTMF, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, sip_options, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROMISCREDIR, SIP_REALTIME, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USEREQPHONE, sip_peer::sipoptions, sip_peer::subscribecontext, text, sip_peer::tohost, transfermode2str(), TRUE, sip_peer::useragent, sip_peer::username, sip_auth::username, ast_variable::value, and sip_peer::vmexten.
Referenced by manager_sip_show_peer(), and sip_show_peer().
10005 { 10006 char status[30] = ""; 10007 char cbuf[256]; 10008 struct sip_peer *peer; 10009 char codec_buf[512]; 10010 struct ast_codec_pref *pref; 10011 struct ast_variable *v; 10012 struct sip_auth *auth; 10013 int x = 0, codec = 0, load_realtime; 10014 int realtimepeers; 10015 10016 realtimepeers = ast_check_realtime("sippeers"); 10017 10018 if (argc < 4) 10019 return RESULT_SHOWUSAGE; 10020 10021 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10022 peer = find_peer(argv[3], NULL, load_realtime); 10023 if (s) { /* Manager */ 10024 if (peer) { 10025 const char *id = astman_get_header(m,"ActionID"); 10026 10027 astman_append(s, "Response: Success\r\n"); 10028 if (!ast_strlen_zero(id)) 10029 astman_append(s, "ActionID: %s\r\n",id); 10030 } else { 10031 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]); 10032 astman_send_error(s, m, cbuf); 10033 return 0; 10034 } 10035 } 10036 if (peer && type==0 ) { /* Normal listing */ 10037 ast_cli(fd,"\n\n"); 10038 ast_cli(fd, " * Name : %s\n", peer->name); 10039 if (realtimepeers) { /* Realtime is enabled */ 10040 ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 10041 } 10042 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 10043 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 10044 for (auth = peer->auth; auth; auth = auth->next) { 10045 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 10046 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 10047 } 10048 ast_cli(fd, " Context : %s\n", peer->context); 10049 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 10050 ast_cli(fd, " Language : %s\n", peer->language); 10051 if (!ast_strlen_zero(peer->accountcode)) 10052 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 10053 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 10054 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 10055 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 10056 if (!ast_strlen_zero(peer->fromuser)) 10057 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 10058 if (!ast_strlen_zero(peer->fromdomain)) 10059 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 10060 ast_cli(fd, " Callgroup : "); 10061 print_group(fd, peer->callgroup, 0); 10062 ast_cli(fd, " Pickupgroup : "); 10063 print_group(fd, peer->pickupgroup, 0); 10064 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 10065 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 10066 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 10067 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 10068 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 10069 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 10070 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 10071 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 10072 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))); 10073 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10074 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 10075 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 10076 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10077 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 10078 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 10079 #endif 10080 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 10081 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 10082 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 10083 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 10084 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 10085 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 10086 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10087 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10088 10089 /* - is enumerated */ 10090 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10091 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 10092 ast_cli(fd, " ToHost : %s\n", peer->tohost); 10093 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)); 10094 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 10095 if (!ast_strlen_zero(global_regcontext)) 10096 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 10097 ast_cli(fd, " Def. Username: %s\n", peer->username); 10098 ast_cli(fd, " SIP Options : "); 10099 if (peer->sipoptions) { 10100 int lastoption = -1; 10101 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10102 if (sip_options[x].id != lastoption) { 10103 if (peer->sipoptions & sip_options[x].id) 10104 ast_cli(fd, "%s ", sip_options[x].text); 10105 lastoption = x; 10106 } 10107 } 10108 } else 10109 ast_cli(fd, "(none)"); 10110 10111 ast_cli(fd, "\n"); 10112 ast_cli(fd, " Codecs : "); 10113 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10114 ast_cli(fd, "%s\n", codec_buf); 10115 ast_cli(fd, " Codec Order : ("); 10116 print_codec_to_cli(fd, &peer->prefs); 10117 ast_cli(fd, ")\n"); 10118 10119 ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No"); 10120 ast_cli(fd, " Status : "); 10121 peer_status(peer, status, sizeof(status)); 10122 ast_cli(fd, "%s\n",status); 10123 ast_cli(fd, " Useragent : %s\n", peer->useragent); 10124 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 10125 if (peer->chanvars) { 10126 ast_cli(fd, " Variables :\n"); 10127 for (v = peer->chanvars ; v ; v = v->next) 10128 ast_cli(fd, " %s = %s\n", v->name, v->value); 10129 } 10130 ast_cli(fd,"\n"); 10131 ASTOBJ_UNREF(peer,sip_destroy_peer); 10132 } else if (peer && type == 1) { /* manager listing */ 10133 char buf[256]; 10134 astman_append(s, "Channeltype: SIP\r\n"); 10135 astman_append(s, "ObjectName: %s\r\n", peer->name); 10136 astman_append(s, "ChanObjectType: peer\r\n"); 10137 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 10138 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 10139 astman_append(s, "Context: %s\r\n", peer->context); 10140 astman_append(s, "Language: %s\r\n", peer->language); 10141 if (!ast_strlen_zero(peer->accountcode)) 10142 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 10143 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 10144 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 10145 if (!ast_strlen_zero(peer->fromuser)) 10146 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 10147 if (!ast_strlen_zero(peer->fromdomain)) 10148 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 10149 astman_append(s, "Callgroup: "); 10150 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup)); 10151 astman_append(s, "Pickupgroup: "); 10152 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup)); 10153 astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox); 10154 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 10155 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 10156 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 10157 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 10158 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 10159 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 10160 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 10161 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))); 10162 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10163 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 10164 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 10165 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 10166 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 10167 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 10168 10169 /* - is enumerated */ 10170 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10171 astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg); 10172 astman_append(s, "ToHost: %s\r\n", peer->tohost); 10173 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)); 10174 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)); 10175 astman_append(s, "Default-Username: %s\r\n", peer->username); 10176 if (!ast_strlen_zero(global_regcontext)) 10177 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 10178 astman_append(s, "Codecs: "); 10179 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10180 astman_append(s, "%s\r\n", codec_buf); 10181 astman_append(s, "CodecOrder: "); 10182 pref = &peer->prefs; 10183 for(x = 0; x < 32 ; x++) { 10184 codec = ast_codec_pref_index(pref,x); 10185 if (!codec) 10186 break; 10187 astman_append(s, "%s", ast_getformatname(codec)); 10188 if (x < 31 && ast_codec_pref_index(pref,x+1)) 10189 astman_append(s, ","); 10190 } 10191 10192 astman_append(s, "\r\n"); 10193 astman_append(s, "Status: "); 10194 peer_status(peer, status, sizeof(status)); 10195 astman_append(s, "%s\r\n", status); 10196 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 10197 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 10198 if (peer->chanvars) { 10199 for (v = peer->chanvars ; v ; v = v->next) { 10200 astman_append(s, "ChanVariable:\n"); 10201 astman_append(s, " %s,%s\r\n", v->name, v->value); 10202 } 10203 } 10204 10205 ASTOBJ_UNREF(peer,sip_destroy_peer); 10206 10207 } else { 10208 ast_cli(fd,"Peer %s not found.\n", argv[3]); 10209 ast_cli(fd,"\n"); 10210 } 10211 10212 return RESULT_SUCCESS; 10213 }
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 9554 of file chan_sip.c.
References ast_check_realtime(), ast_cli(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, FORMAT2, id, name, peer_status(), peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, s, SIP_NAT_ROUTE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_VIDEOSUPPORT, SIP_REALTIME, and TRUE.
Referenced by manager_sip_show_peers(), and sip_show_peers().
09555 { 09556 regex_t regexbuf; 09557 int havepattern = FALSE; 09558 09559 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 09560 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 09561 09562 char name[256]; 09563 int total_peers = 0; 09564 int peers_mon_online = 0; 09565 int peers_mon_offline = 0; 09566 int peers_unmon_offline = 0; 09567 int peers_unmon_online = 0; 09568 const char *id; 09569 char idtext[256] = ""; 09570 int realtimepeers; 09571 09572 realtimepeers = ast_check_realtime("sippeers"); 09573 09574 if (s) { /* Manager - get ActionID */ 09575 id = astman_get_header(m,"ActionID"); 09576 if (!ast_strlen_zero(id)) 09577 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 09578 } 09579 09580 switch (argc) { 09581 case 5: 09582 if (!strcasecmp(argv[3], "like")) { 09583 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 09584 return RESULT_SHOWUSAGE; 09585 havepattern = TRUE; 09586 } else 09587 return RESULT_SHOWUSAGE; 09588 case 3: 09589 break; 09590 default: 09591 return RESULT_SHOWUSAGE; 09592 } 09593 09594 if (!s) /* Normal list */ 09595 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 09596 09597 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09598 char status[20] = ""; 09599 char srch[2000]; 09600 char pstatus; 09601 09602 ASTOBJ_RDLOCK(iterator); 09603 09604 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09605 ASTOBJ_UNLOCK(iterator); 09606 continue; 09607 } 09608 09609 if (!ast_strlen_zero(iterator->username) && !s) 09610 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 09611 else 09612 ast_copy_string(name, iterator->name, sizeof(name)); 09613 09614 pstatus = peer_status(iterator, status, sizeof(status)); 09615 if (pstatus == 1) 09616 peers_mon_online++; 09617 else if (pstatus == 0) 09618 peers_mon_offline++; 09619 else { 09620 if (iterator->addr.sin_port == 0) 09621 peers_unmon_offline++; 09622 else 09623 peers_unmon_online++; 09624 } 09625 09626 snprintf(srch, sizeof(srch), FORMAT, name, 09627 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 09628 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 09629 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 09630 iterator->ha ? " A " : " ", /* permit/deny */ 09631 ntohs(iterator->addr.sin_port), status, 09632 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 09633 09634 if (!s) {/* Normal CLI list */ 09635 ast_cli(fd, FORMAT, name, 09636 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 09637 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 09638 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 09639 iterator->ha ? " A " : " ", /* permit/deny */ 09640 09641 ntohs(iterator->addr.sin_port), status, 09642 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 09643 } else { /* Manager format */ 09644 /* The names here need to be the same as other channels */ 09645 astman_append(s, 09646 "Event: PeerEntry\r\n%s" 09647 "Channeltype: SIP\r\n" 09648 "ObjectName: %s\r\n" 09649 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 09650 "IPaddress: %s\r\n" 09651 "IPport: %d\r\n" 09652 "Dynamic: %s\r\n" 09653 "Natsupport: %s\r\n" 09654 "VideoSupport: %s\r\n" 09655 "ACL: %s\r\n" 09656 "Status: %s\r\n" 09657 "RealtimeDevice: %s\r\n\r\n", 09658 idtext, 09659 iterator->name, 09660 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 09661 ntohs(iterator->addr.sin_port), 09662 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 09663 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 09664 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 09665 iterator->ha ? "yes" : "no", /* permit/deny */ 09666 status, 09667 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 09668 } 09669 09670 ASTOBJ_UNLOCK(iterator); 09671 09672 total_peers++; 09673 } while(0) ); 09674 09675 if (!s) 09676 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 09677 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 09678 09679 if (havepattern) 09680 regfree(®exbuf); 09681 09682 if (total) 09683 *total = total_peers; 09684 09685 09686 return RESULT_SUCCESS; 09687 #undef FORMAT 09688 #undef FORMAT2 09689 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 14162 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, LOG_ERROR, LOG_WARNING, parse(), sip_pvt::rtp, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, type, and sip_pvt::vrtp.
14163 { 14164 struct ast_rtp_quality qos; 14165 struct sip_pvt *p = chan->tech_pvt; 14166 char *all = "", *parse = ast_strdupa(preparse); 14167 AST_DECLARE_APP_ARGS(args, 14168 AST_APP_ARG(param); 14169 AST_APP_ARG(type); 14170 AST_APP_ARG(field); 14171 ); 14172 AST_STANDARD_APP_ARGS(args, parse); 14173 14174 /* Sanity check */ 14175 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 14176 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 14177 return 0; 14178 } 14179 14180 if (strcasecmp(args.param, "rtpqos")) 14181 return 0; 14182 14183 memset(buf, 0, buflen); 14184 memset(&qos, 0, sizeof(qos)); 14185 14186 if (strcasecmp(args.type, "AUDIO") == 0) { 14187 all = ast_rtp_get_quality(p->rtp, &qos); 14188 } else if (strcasecmp(args.type, "VIDEO") == 0) { 14189 all = ast_rtp_get_quality(p->vrtp, &qos); 14190 } 14191 14192 if (strcasecmp(args.field, "local_ssrc") == 0) 14193 snprintf(buf, buflen, "%u", qos.local_ssrc); 14194 else if (strcasecmp(args.field, "local_lostpackets") == 0) 14195 snprintf(buf, buflen, "%u", qos.local_lostpackets); 14196 else if (strcasecmp(args.field, "local_jitter") == 0) 14197 snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0); 14198 else if (strcasecmp(args.field, "local_count") == 0) 14199 snprintf(buf, buflen, "%u", qos.local_count); 14200 else if (strcasecmp(args.field, "remote_ssrc") == 0) 14201 snprintf(buf, buflen, "%u", qos.remote_ssrc); 14202 else if (strcasecmp(args.field, "remote_lostpackets") == 0) 14203 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 14204 else if (strcasecmp(args.field, "remote_jitter") == 0) 14205 snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0); 14206 else if (strcasecmp(args.field, "remote_count") == 0) 14207 snprintf(buf, buflen, "%u", qos.remote_count); 14208 else if (strcasecmp(args.field, "rtt") == 0) 14209 snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0); 14210 else if (strcasecmp(args.field, "all") == 0) 14211 ast_copy_string(buf, all, buflen); 14212 else { 14213 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 14214 return -1; 14215 } 14216 return 0; 14217 }
static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 2148 of file chan_sip.c.
References sip_request::data, sip_request::len, and sip_request::lines.
Referenced by send_request(), and send_response().
02149 { 02150 if (!req->lines) { 02151 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 02152 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 02153 req->len += strlen(req->data + req->len); 02154 } 02155 }
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 5942 of file chan_sip.c.
References ast_build_string(), ast_codec_pref_getsize(), AST_FORMAT_G729A, AST_FORMAT_ILBC, ast_getformatname(), ast_rtp_codec_getpref(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), AST_RTP_OPT_G726_NONSTANDARD, ast_test_flag, ast_verbose(), sip_pvt::flags, fmt, sip_pvt::rtp, and SIP_G726_NONSTANDARD.
Referenced by add_sdp().
05945 { 05946 int rtp_code; 05947 struct ast_format_list fmt; 05948 05949 05950 if (debug) 05951 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 05952 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 05953 return; 05954 05955 if (p->rtp) { 05956 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 05957 fmt = ast_codec_pref_getsize(pref, codec); 05958 } 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 */ 05959 return; 05960 ast_build_string(m_buf, m_size, " %d", rtp_code); 05961 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 05962 ast_rtp_lookup_mime_subtype(1, codec, 05963 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 05964 sample_rate); 05965 if (codec == AST_FORMAT_G729A) { 05966 /* Indicate that we don't support VAD (G.729 annex B) */ 05967 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 05968 } else if (codec == AST_FORMAT_ILBC) { 05969 /* Add information about us using only 20/30 ms packetization */ 05970 ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 05971 } 05972 05973 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 05974 *min_packet_size = fmt.cur_ms; 05975 05976 /* Our first codec packetization processed cannot be less than zero */ 05977 if ((*min_packet_size) == 0 && fmt.cur_ms) 05978 *min_packet_size = fmt.cur_ms; 05979 }
static int add_digit | ( | struct sip_request * | req, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Add DTMF INFO tone to sip message.
Definition at line 5910 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_digit().
05911 { 05912 char tmp[256]; 05913 05914 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 05915 add_header(req, "Content-Type", "application/dtmf-relay"); 05916 add_header_contentLength(req, strlen(tmp)); 05917 add_line(req, tmp); 05918 return 0; 05919 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 5301 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.
05302 { 05303 int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */ 05304 05305 if (req->headers == SIP_MAX_HEADERS) { 05306 ast_log(LOG_WARNING, "Out of SIP header space\n"); 05307 return -1; 05308 } 05309 05310 if (req->lines) { 05311 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 05312 return -1; 05313 } 05314 05315 if (maxlen <= 0) { 05316 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 05317 return -1; 05318 } 05319 05320 req->header[req->headers] = req->data + req->len; 05321 05322 if (compactheaders) 05323 var = find_alias(var, var); 05324 05325 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 05326 req->len += strlen(req->header[req->headers]); 05327 req->headers++; 05328 if (req->headers < SIP_MAX_HEADERS) 05329 req->headers++; 05330 else 05331 ast_log(LOG_WARNING, "Out of SIP header space... Will generate broken SIP message\n"); 05332 05333 return 0; 05334 }
static int add_header_contentLength | ( | struct sip_request * | req, | |
int | len | |||
) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 5337 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().
05338 { 05339 char clen[10]; 05340 05341 snprintf(clen, sizeof(clen), "%d", len); 05342 return add_header(req, "Content-Length", clen); 05343 }
static int add_line | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 5346 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.
05347 { 05348 if (req->lines == SIP_MAX_LINES) { 05349 ast_log(LOG_WARNING, "Out of SIP line space\n"); 05350 return -1; 05351 } 05352 if (!req->lines) { 05353 /* Add extra empty return */ 05354 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 05355 req->len += strlen(req->data + req->len); 05356 } 05357 if (req->len >= sizeof(req->data) - 4) { 05358 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 05359 return -1; 05360 } 05361 req->line[req->lines] = req->data + req->len; 05362 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 05363 req->len += strlen(req->line[req->lines]); 05364 req->lines++; 05365 return 0; 05366 }
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 6115 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().
06118 { 06119 int rtp_code; 06120 06121 if (debug) 06122 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 06123 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 06124 return; 06125 06126 ast_build_string(m_buf, m_size, " %d", rtp_code); 06127 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06128 ast_rtp_lookup_mime_subtype(0, format, 0), 06129 sample_rate); 06130 if (format == AST_RTP_DTMF) 06131 /* Indicate we support DTMF and FLASH... */ 06132 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 06133 }
static struct sip_auth * add_realm_authentication | ( | struct sip_auth * | authlist, | |
char * | configuration, | |||
int | lineno | |||
) | [static] |
Add realm authentication in list.
Definition at line 15687 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, secret, strsep(), and username.
Referenced by build_peer().
15688 { 15689 char authcopy[256]; 15690 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 15691 char *stringp; 15692 struct sip_auth *a, *b, *auth; 15693 15694 if (ast_strlen_zero(configuration)) 15695 return authlist; 15696 15697 if (option_debug) 15698 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 15699 15700 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 15701 stringp = authcopy; 15702 15703 username = stringp; 15704 realm = strrchr(stringp, '@'); 15705 if (realm) 15706 *realm++ = '\0'; 15707 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 15708 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 15709 return authlist; 15710 } 15711 stringp = username; 15712 username = strsep(&stringp, ":"); 15713 if (username) { 15714 secret = strsep(&stringp, ":"); 15715 if (!secret) { 15716 stringp = username; 15717 md5secret = strsep(&stringp,"#"); 15718 } 15719 } 15720 if (!(auth = ast_calloc(1, sizeof(*auth)))) 15721 return authlist; 15722 15723 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 15724 ast_copy_string(auth->username, username, sizeof(auth->username)); 15725 if (secret) 15726 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 15727 if (md5secret) 15728 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 15729 15730 /* find the end of the list */ 15731 for (b = NULL, a = authlist; a ; b = a, a = a->next) 15732 ; 15733 if (b) 15734 b->next = auth; /* Add structure add end of list */ 15735 else 15736 authlist = auth; 15737 15738 if (option_verbose > 2) 15739 ast_verbose("Added authentication for realm %s\n", realm); 15740 15741 return authlist; 15742 15743 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 5467 of file chan_sip.c.
References add_header(), sip_route::hop, and sip_route::next.
Referenced by reqprep().
05468 { 05469 char r[BUFSIZ*2], *p; 05470 int n, rem = sizeof(r); 05471 05472 if (!route) 05473 return; 05474 05475 p = r; 05476 for (;route ; route = route->next) { 05477 n = strlen(route->hop); 05478 if (rem < n+3) /* we need room for ",<route>" */ 05479 break; 05480 if (p != r) { /* add a separator after fist route */ 05481 *p++ = ','; 05482 --rem; 05483 } 05484 *p++ = '<'; 05485 ast_copy_string(p, route->hop, rem); /* cannot fail */ 05486 p += n; 05487 *p++ = '>'; 05488 rem -= (n+2); 05489 } 05490 *p = '\0'; 05491 add_header(req, "Route", r); 05492 }
static enum sip_result add_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add Session Description Protocol message.
Definition at line 6138 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.
06139 { 06140 int len = 0; 06141 int alreadysent = 0; 06142 06143 struct sockaddr_in sin; 06144 struct sockaddr_in vsin; 06145 struct sockaddr_in dest; 06146 struct sockaddr_in vdest = { 0, }; 06147 06148 /* SDP fields */ 06149 char *version = "v=0\r\n"; /* Protocol version */ 06150 char *subject = "s=session\r\n"; /* Subject of the session */ 06151 char owner[256]; /* Session owner/creator */ 06152 char connection[256]; /* Connection data */ 06153 char *stime = "t=0 0\r\n"; /* Time the session is active */ 06154 char bandwidth[256] = ""; /* Max bitrate */ 06155 char *hold; 06156 char m_audio[256]; /* Media declaration line for audio */ 06157 char m_video[256]; /* Media declaration line for video */ 06158 char a_audio[1024]; /* Attributes for audio */ 06159 char a_video[1024]; /* Attributes for video */ 06160 char *m_audio_next = m_audio; 06161 char *m_video_next = m_video; 06162 size_t m_audio_left = sizeof(m_audio); 06163 size_t m_video_left = sizeof(m_video); 06164 char *a_audio_next = a_audio; 06165 char *a_video_next = a_video; 06166 size_t a_audio_left = sizeof(a_audio); 06167 size_t a_video_left = sizeof(a_video); 06168 06169 int x; 06170 int capability; 06171 int needvideo = FALSE; 06172 int debug = sip_debug_test_pvt(p); 06173 int min_audio_packet_size = 0; 06174 int min_video_packet_size = 0; 06175 06176 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 06177 06178 if (!p->rtp) { 06179 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 06180 return AST_FAILURE; 06181 } 06182 06183 /* Set RTP Session ID and version */ 06184 if (!p->sessionid) { 06185 p->sessionid = getpid(); 06186 p->sessionversion = p->sessionid; 06187 } else 06188 p->sessionversion++; 06189 06190 /* Get our addresses */ 06191 ast_rtp_get_us(p->rtp, &sin); 06192 if (p->vrtp) 06193 ast_rtp_get_us(p->vrtp, &vsin); 06194 06195 /* Is this a re-invite to move the media out, then use the original offer from caller */ 06196 if (p->redirip.sin_addr.s_addr) { 06197 dest.sin_port = p->redirip.sin_port; 06198 dest.sin_addr = p->redirip.sin_addr; 06199 } else { 06200 dest.sin_addr = p->ourip; 06201 dest.sin_port = sin.sin_port; 06202 } 06203 06204 capability = p->jointcapability; 06205 06206 06207 if (option_debug > 1) { 06208 char codecbuf[BUFSIZ]; 06209 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"); 06210 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 06211 } 06212 06213 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 06214 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 06215 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 06216 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 06217 } 06218 #endif 06219 06220 /* Check if we need video in this call */ 06221 if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 06222 if (p->vrtp) { 06223 needvideo = TRUE; 06224 if (option_debug > 1) 06225 ast_log(LOG_DEBUG, "This call needs video offers!\n"); 06226 } else if (option_debug > 1) 06227 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n"); 06228 } 06229 06230 06231 /* Ok, we need video. Let's add what we need for video and set codecs. 06232 Video is handled differently than audio since we can not transcode. */ 06233 if (needvideo) { 06234 /* Determine video destination */ 06235 if (p->vredirip.sin_addr.s_addr) { 06236 vdest.sin_addr = p->vredirip.sin_addr; 06237 vdest.sin_port = p->vredirip.sin_port; 06238 } else { 06239 vdest.sin_addr = p->ourip; 06240 vdest.sin_port = vsin.sin_port; 06241 } 06242 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 06243 06244 /* Build max bitrate string */ 06245 if (p->maxcallbitrate) 06246 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 06247 if (debug) 06248 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 06249 } 06250 06251 if (debug) 06252 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 06253 06254 /* Start building generic SDP headers */ 06255 06256 /* We break with the "recommendation" and send our IP, in order that our 06257 peer doesn't have to ast_gethostbyname() us */ 06258 06259 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 06260 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 06261 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 06262 06263 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) 06264 hold = "a=recvonly\r\n"; 06265 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) 06266 hold = "a=inactive\r\n"; 06267 else 06268 hold = "a=sendrecv\r\n"; 06269 06270 /* Now, start adding audio codecs. These are added in this order: 06271 - First what was requested by the calling channel 06272 - Then preferences in order from sip.conf device config for this peer/user 06273 - Then other codecs in capabilities, including video 06274 */ 06275 06276 /* Prefer the audio codec we were requested to use, first, no matter what 06277 Note that p->prefcodec can include video codecs, so mask them out 06278 */ 06279 if (capability & p->prefcodec) { 06280 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 06281 06282 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06283 &m_audio_next, &m_audio_left, 06284 &a_audio_next, &a_audio_left, 06285 debug, &min_audio_packet_size); 06286 alreadysent |= codec; 06287 } 06288 06289 /* Start by sending our preferred audio codecs */ 06290 for (x = 0; x < 32; x++) { 06291 int codec; 06292 06293 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 06294 break; 06295 06296 if (!(capability & codec)) 06297 continue; 06298 06299 if (alreadysent & codec) 06300 continue; 06301 06302 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06303 &m_audio_next, &m_audio_left, 06304 &a_audio_next, &a_audio_left, 06305 debug, &min_audio_packet_size); 06306 alreadysent |= codec; 06307 } 06308 06309 /* Now send any other common audio and video codecs, and non-codec formats: */ 06310 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 06311 if (!(capability & x)) /* Codec not requested */ 06312 continue; 06313 06314 if (alreadysent & x) /* Already added to SDP */ 06315 continue; 06316 06317 if (x <= AST_FORMAT_MAX_AUDIO) 06318 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 06319 &m_audio_next, &m_audio_left, 06320 &a_audio_next, &a_audio_left, 06321 debug, &min_audio_packet_size); 06322 else 06323 add_codec_to_sdp(p, x, 90000, 06324 &m_video_next, &m_video_left, 06325 &a_video_next, &a_video_left, 06326 debug, &min_video_packet_size); 06327 } 06328 06329 /* Now add DTMF RFC2833 telephony-event as a codec */ 06330 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 06331 if (!(p->jointnoncodeccapability & x)) 06332 continue; 06333 06334 add_noncodec_to_sdp(p, x, 8000, 06335 &m_audio_next, &m_audio_left, 06336 &a_audio_next, &a_audio_left, 06337 debug); 06338 } 06339 06340 if (option_debug > 2) 06341 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 06342 06343 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 06344 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 06345 06346 if (min_audio_packet_size) 06347 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 06348 06349 if (min_video_packet_size) 06350 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 06351 06352 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 06353 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 06354 06355 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 06356 if (needvideo) 06357 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 06358 06359 len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold); 06360 if (needvideo) /* only if video response is appropriate */ 06361 len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold); 06362 06363 add_header(resp, "Content-Type", "application/sdp"); 06364 add_header_contentLength(resp, len); 06365 add_line(resp, version); 06366 add_line(resp, owner); 06367 add_line(resp, subject); 06368 add_line(resp, connection); 06369 if (needvideo) /* only if video response is appropriate */ 06370 add_line(resp, bandwidth); 06371 add_line(resp, stime); 06372 add_line(resp, m_audio); 06373 add_line(resp, a_audio); 06374 add_line(resp, hold); 06375 if (needvideo) { /* only if video response is appropriate */ 06376 add_line(resp, m_video); 06377 add_line(resp, a_video); 06378 add_line(resp, hold); /* Repeat hold for the video stream */ 06379 } 06380 06381 /* Update lastrtprx when we send our SDP */ 06382 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 06383 06384 if (option_debug > 2) { 06385 char buf[BUFSIZ]; 06386 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, BUFSIZ, capability)); 06387 } 06388 06389 return AST_SUCCESS; 06390 }
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 15623 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), LOG_DEBUG, LOG_WARNING, and sipdebug.
15624 { 15625 struct domain *d; 15626 15627 if (ast_strlen_zero(domain)) { 15628 ast_log(LOG_WARNING, "Zero length domain.\n"); 15629 return 1; 15630 } 15631 15632 if (!(d = ast_calloc(1, sizeof(*d)))) 15633 return 0; 15634 15635 ast_copy_string(d->domain, domain, sizeof(d->domain)); 15636 15637 if (!ast_strlen_zero(context)) 15638 ast_copy_string(d->context, context, sizeof(d->context)); 15639 15640 d->mode = mode; 15641 15642 AST_LIST_LOCK(&domain_list); 15643 AST_LIST_INSERT_TAIL(&domain_list, d, list); 15644 AST_LIST_UNLOCK(&domain_list); 15645 15646 if (sipdebug) 15647 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 15648 15649 return 1; 15650 }
static int add_t38_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add T.38 Session Description Protocol message.
Definition at line 6018 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().
06019 { 06020 int len = 0; 06021 int x = 0; 06022 struct sockaddr_in udptlsin; 06023 char v[256] = ""; 06024 char s[256] = ""; 06025 char o[256] = ""; 06026 char c[256] = ""; 06027 char t[256] = ""; 06028 char m_modem[256]; 06029 char a_modem[1024]; 06030 char *m_modem_next = m_modem; 06031 size_t m_modem_left = sizeof(m_modem); 06032 char *a_modem_next = a_modem; 06033 size_t a_modem_left = sizeof(a_modem); 06034 struct sockaddr_in udptldest = { 0, }; 06035 int debug; 06036 06037 debug = sip_debug_test_pvt(p); 06038 len = 0; 06039 if (!p->udptl) { 06040 ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n"); 06041 return -1; 06042 } 06043 06044 if (!p->sessionid) { 06045 p->sessionid = getpid(); 06046 p->sessionversion = p->sessionid; 06047 } else 06048 p->sessionversion++; 06049 06050 /* Our T.38 end is */ 06051 ast_udptl_get_us(p->udptl, &udptlsin); 06052 06053 /* Determine T.38 UDPTL destination */ 06054 if (p->udptlredirip.sin_addr.s_addr) { 06055 udptldest.sin_port = p->udptlredirip.sin_port; 06056 udptldest.sin_addr = p->udptlredirip.sin_addr; 06057 } else { 06058 udptldest.sin_addr = p->ourip; 06059 udptldest.sin_port = udptlsin.sin_port; 06060 } 06061 06062 if (debug) 06063 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 06064 06065 /* We break with the "recommendation" and send our IP, in order that our 06066 peer doesn't have to ast_gethostbyname() us */ 06067 06068 if (debug) { 06069 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 06070 p->t38.capability, 06071 p->t38.peercapability, 06072 p->t38.jointcapability); 06073 } 06074 snprintf(v, sizeof(v), "v=0\r\n"); 06075 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr)); 06076 snprintf(s, sizeof(s), "s=session\r\n"); 06077 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr)); 06078 snprintf(t, sizeof(t), "t=0 0\r\n"); 06079 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 06080 06081 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 06082 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 06083 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 06084 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 06085 if ((x = t38_get_rate(p->t38.jointcapability))) 06086 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 06087 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0); 06088 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0); 06089 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0); 06090 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 06091 x = ast_udptl_get_local_max_datagram(p->udptl); 06092 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 06093 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 06094 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 06095 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 06096 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem); 06097 add_header(resp, "Content-Type", "application/sdp"); 06098 add_header_contentLength(resp, len); 06099 add_line(resp, v); 06100 add_line(resp, o); 06101 add_line(resp, s); 06102 add_line(resp, c); 06103 add_line(resp, t); 06104 add_line(resp, m_modem); 06105 add_line(resp, a_modem); 06106 06107 /* Update lastrtprx when we send our SDP */ 06108 p->lastrtprx = p->lastrtptx = time(NULL); 06109 06110 return 0; 06111 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 5899 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_message_with_text().
05900 { 05901 /* XXX Convert \n's to \r\n's XXX */ 05902 add_header(req, "Content-Type", "text/plain"); 05903 add_header_contentLength(req, strlen(text)); 05904 add_line(req, text); 05905 return 0; 05906 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 5923 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_vidupdate().
05924 { 05925 const char *xml_is_a_huge_waste_of_space = 05926 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 05927 " <media_control>\r\n" 05928 " <vc_primitive>\r\n" 05929 " <to_encoder>\r\n" 05930 " <picture_fast_update>\r\n" 05931 " </picture_fast_update>\r\n" 05932 " </to_encoder>\r\n" 05933 " </vc_primitive>\r\n" 05934 " </media_control>\r\n"; 05935 add_header(req, "Content-Type", "application/media_control+xml"); 05936 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 05937 add_line(req, xml_is_a_huge_waste_of_space); 05938 return 0; 05939 }
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 5846 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().
05847 { 05848 char tmpdat[256]; 05849 struct tm tm; 05850 time_t t = time(NULL); 05851 05852 gmtime_r(&t, &tm); 05853 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 05854 add_header(req, "Date", tmpdat); 05855 }
static void append_history_full | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1837 of file chan_sip.c.
References append_history_va().
01838 { 01839 va_list ap; 01840 01841 if (!p) 01842 return; 01843 va_start(ap, fmt); 01844 append_history_va(p, fmt, ap); 01845 va_end(ap); 01846 01847 return; 01848 }
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 1817 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, free, and strsep().
Referenced by append_history_full().
01818 { 01819 char buf[80], *c = buf; /* max history length */ 01820 struct sip_history *hist; 01821 int l; 01822 01823 vsnprintf(buf, sizeof(buf), fmt, ap); 01824 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 01825 l = strlen(buf) + 1; 01826 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) 01827 return; 01828 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 01829 free(hist); 01830 return; 01831 } 01832 memcpy(hist->event, buf, l); 01833 AST_LIST_INSERT_TAIL(p->history, hist, list); 01834 }
AST_LIST_HEAD_NOLOCK | ( | sip_history_head | , | |
sip_history | ||||
) |
history list, entry in sip_pvt
static AST_LIST_HEAD_STATIC | ( | domain_list | , | |
domain | ||||
) | [static] |
The SIP domain list
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_DEFAULT | , | |||
"Session Initiation Protocol (SIP)" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload | |||
) |
AST_MUTEX_DEFINE_STATIC | ( | sip_reload_lock | ) |
AST_MUTEX_DEFINE_STATIC | ( | monlock | ) |
AST_MUTEX_DEFINE_STATIC | ( | netlock | ) |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
AST_MUTEX_DEFINE_STATIC | ( | iflock | ) |
Protect the SIP dialog list (of sip_pvt's).
static void ast_quiet_chan | ( | struct ast_channel * | chan | ) | [static] |
Turn off generator data XXX Does this function belong in the SIP channel?
Definition at line 12751 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().
12752 { 12753 if (chan && chan->_state == AST_STATE_UP) { 12754 if (chan->generatordata) 12755 ast_deactivate_generator(chan); 12756 } 12757 }
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 1777 of file chan_sip.c.
References ahp, ast_apply_ha(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), AST_SUCCESS, externexpire, externhost, externrefresh, hp, localaddr, LOG_DEBUG, LOG_NOTICE, and option_debug.
Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_register(), and transmit_response_using_temp().
01778 { 01779 struct sockaddr_in theirs, ours; 01780 01781 /* Get our local information */ 01782 ast_ouraddrfor(them, us); 01783 theirs.sin_addr = *them; 01784 ours.sin_addr = *us; 01785 01786 if (localaddr && externip.sin_addr.s_addr && 01787 (ast_apply_ha(localaddr, &theirs)) && 01788 (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) { 01789 if (externexpire && time(NULL) >= externexpire) { 01790 struct ast_hostent ahp; 01791 struct hostent *hp; 01792 01793 externexpire = time(NULL) + externrefresh; 01794 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01795 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01796 } else 01797 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01798 } 01799 *us = externip.sin_addr; 01800 if (option_debug) { 01801 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 01802 ast_inet_ntoa(*(struct in_addr *)&them->s_addr)); 01803 } 01804 } else if (bindaddr.sin_addr.s_addr) 01805 *us = bindaddr.sin_addr; 01806 return AST_SUCCESS; 01807 }
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 12761 of file chan_sip.c.
References ast_channel::_state, ast_cdr_append(), ast_channel_masquerade(), ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_state2str(), sip_dual::chan1, sip_dual::chan2, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, and option_debug.
12762 { 12763 int res = 0; 12764 struct ast_channel *peera = NULL, 12765 *peerb = NULL, 12766 *peerc = NULL, 12767 *peerd = NULL; 12768 12769 12770 /* We will try to connect the transferee with the target and hangup 12771 all channels to the transferer */ 12772 if (option_debug > 3) { 12773 ast_log(LOG_DEBUG, "Sip transfer:--------------------\n"); 12774 if (transferer->chan1) 12775 ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 12776 else 12777 ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n"); 12778 if (target->chan1) 12779 ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 12780 else 12781 ast_log(LOG_DEBUG, "-- No target first channel ---\n"); 12782 if (transferer->chan2) 12783 ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 12784 else 12785 ast_log(LOG_DEBUG, "-- No bridged call to transferee\n"); 12786 if (target->chan2) 12787 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)"); 12788 else 12789 ast_log(LOG_DEBUG, "-- No target second channel ---\n"); 12790 ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n"); 12791 } 12792 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 12793 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 12794 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 12795 peerc = transferer->chan2; /* Asterisk to Transferee */ 12796 peerd = target->chan2; /* Asterisk to Target */ 12797 if (option_debug > 2) 12798 ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n"); 12799 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 12800 peera = target->chan1; /* Transferer to PBX -> target channel */ 12801 peerb = transferer->chan1; /* Transferer to IVR*/ 12802 peerc = target->chan2; /* Asterisk to Target */ 12803 peerd = transferer->chan2; /* Nothing */ 12804 if (option_debug > 2) 12805 ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n"); 12806 } 12807 12808 if (peera && peerb && peerc && (peerb != peerc)) { 12809 ast_quiet_chan(peera); /* Stop generators */ 12810 ast_quiet_chan(peerb); 12811 ast_quiet_chan(peerc); 12812 if (peerd) 12813 ast_quiet_chan(peerd); 12814 12815 /* Fix CDRs so they're attached to the remaining channel */ 12816 if (peera->cdr && peerb->cdr) 12817 peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr); 12818 else if (peera->cdr) 12819 peerb->cdr = peera->cdr; 12820 peera->cdr = NULL; 12821 12822 if (peerb->cdr && peerc->cdr) 12823 peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr); 12824 else if (peerc->cdr) 12825 peerb->cdr = peerc->cdr; 12826 peerc->cdr = NULL; 12827 12828 if (option_debug > 3) 12829 ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 12830 if (ast_channel_masquerade(peerb, peerc)) { 12831 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 12832 res = -1; 12833 } else 12834 ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n"); 12835 return res; 12836 } else { 12837 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 12838 if (transferer->chan1) 12839 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 12840 if (target->chan1) 12841 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 12842 return -1; 12843 } 12844 return 0; 12845 }
static int auto_congest | ( | void * | nothing | ) | [static] |
Scheduled congestion on a call.
Definition at line 2750 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.
02751 { 02752 struct sip_pvt *p = nothing; 02753 02754 ast_mutex_lock(&p->lock); 02755 p->initid = -1; 02756 if (p->owner) { 02757 /* XXX fails on possible deadlock */ 02758 if (!ast_channel_trylock(p->owner)) { 02759 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 02760 append_history(p, "Cong", "Auto-congesting (timer)"); 02761 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 02762 ast_channel_unlock(p->owner); 02763 } 02764 } 02765 ast_mutex_unlock(&p->lock); 02766 return 0; 02767 }
static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 4176 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().
04177 { 04178 char buf[33]; 04179 04180 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip)); 04181 04182 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04183 04184 }
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 4187 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, generate_random_string(), and S_OR.
Referenced by transmit_register().
04188 { 04189 char buf[33]; 04190 04191 const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip)); 04192 04193 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04194 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 6559 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, ast_strlen_zero(), ourport, and STANDARD_SIP_PORT.
Referenced by check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), initreqprep(), register_verify(), and transmit_register().
06560 { 06561 /* Construct Contact: header */ 06562 if (ourport != STANDARD_SIP_PORT) 06563 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); 06564 else 06565 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip)); 06566 }
static struct sip_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static] |
Build peer from configuration (file or realtime static/dynamic).
Definition at line 15953 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, sip_peer::context, sip_peer::defaddr, DEFAULT_MAXMS, destroy_association(), sip_peer::expire, ast_flags::flags, sip_peer::flags, format, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_flags, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, 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, sched, sip_peer::secret, set_peer_defaults(), sip_destroy_peer(), SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_REALTIME, SIP_USEREQPHONE, STANDARD_SIP_PORT, sip_peer::subscribecontext, sip_peer::tohost, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, sip_peer::username, ast_variable::value, and sip_peer::vmexten.
15954 { 15955 struct sip_peer *peer = NULL; 15956 struct ast_ha *oldha = NULL; 15957 int obproxyfound=0; 15958 int found=0; 15959 int firstpass=1; 15960 int format=0; /* Ama flags */ 15961 time_t regseconds = 0; 15962 char *varname = NULL, *varval = NULL; 15963 struct ast_variable *tmpvar = NULL; 15964 struct ast_flags peerflags[2] = {{(0)}}; 15965 struct ast_flags mask[2] = {{(0)}}; 15966 15967 15968 if (!realtime) 15969 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 15970 /* We also use a case-sensitive comparison (unlike find_peer) so 15971 that case changes made to the peer name will be properly handled 15972 during reload 15973 */ 15974 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 15975 15976 if (peer) { 15977 /* Already in the list, remove it and it will be added back (or FREE'd) */ 15978 found = 1; 15979 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 15980 firstpass = 0; 15981 } else { 15982 if (!(peer = ast_calloc(1, sizeof(*peer)))) 15983 return NULL; 15984 15985 if (realtime) 15986 rpeerobjs++; 15987 else 15988 speerobjs++; 15989 ASTOBJ_INIT(peer); 15990 } 15991 /* Note that our peer HAS had its reference count incrased */ 15992 if (firstpass) { 15993 peer->lastmsgssent = -1; 15994 oldha = peer->ha; 15995 peer->ha = NULL; 15996 set_peer_defaults(peer); /* Set peer defaults */ 15997 } 15998 if (!found && name) 15999 ast_copy_string(peer->name, name, sizeof(peer->name)); 16000 16001 /* If we have channel variables, remove them (reload) */ 16002 if (peer->chanvars) { 16003 ast_variables_destroy(peer->chanvars); 16004 peer->chanvars = NULL; 16005 /* XXX should unregister ? */ 16006 } 16007 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 16008 if (handle_common_options(&peerflags[0], &mask[0], v)) 16009 continue; 16010 if (realtime && !strcasecmp(v->name, "regseconds")) { 16011 ast_get_time_t(v->value, ®seconds, 0, NULL); 16012 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 16013 inet_aton(v->value, &(peer->addr.sin_addr)); 16014 } else if (realtime && !strcasecmp(v->name, "name")) 16015 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 16016 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 16017 ast_copy_string(peer->fullcontact, v->value, sizeof(peer->fullcontact)); 16018 ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT); 16019 } else if (!strcasecmp(v->name, "secret")) 16020 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 16021 else if (!strcasecmp(v->name, "md5secret")) 16022 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 16023 else if (!strcasecmp(v->name, "auth")) 16024 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 16025 else if (!strcasecmp(v->name, "callerid")) { 16026 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 16027 } else if (!strcasecmp(v->name, "fullname")) { 16028 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 16029 } else if (!strcasecmp(v->name, "cid_number")) { 16030 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 16031 } else if (!strcasecmp(v->name, "context")) { 16032 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 16033 } else if (!strcasecmp(v->name, "subscribecontext")) { 16034 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 16035 } else if (!strcasecmp(v->name, "fromdomain")) { 16036 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 16037 } else if (!strcasecmp(v->name, "usereqphone")) { 16038 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 16039 } else if (!strcasecmp(v->name, "fromuser")) { 16040 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 16041 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 16042 if (!strcasecmp(v->value, "dynamic")) { 16043 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 16044 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 16045 } else { 16046 /* They'll register with us */ 16047 if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 16048 /* Initialize stuff if this is a new peer, or if it used to be 16049 * non-dynamic before the reload. */ 16050 memset(&peer->addr.sin_addr, 0, 4); 16051 if (peer->addr.sin_port) { 16052 /* If we've already got a port, make it the default rather than absolute */ 16053 peer->defaddr.sin_port = peer->addr.sin_port; 16054 peer->addr.sin_port = 0; 16055 } 16056 } 16057 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16058 } 16059 } else { 16060 /* Non-dynamic. Make sure we become that way if we're not */ 16061 if (peer->expire > -1) 16062 ast_sched_del(sched, peer->expire); 16063 peer->expire = -1; 16064 ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16065 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 16066 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 16067 ASTOBJ_UNREF(peer, sip_destroy_peer); 16068 return NULL; 16069 } 16070 } 16071 if (!strcasecmp(v->name, "outboundproxy")) 16072 obproxyfound=1; 16073 else { 16074 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 16075 if (!peer->addr.sin_port) 16076 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 16077 } 16078 } 16079 } else if (!strcasecmp(v->name, "defaultip")) { 16080 if (ast_get_ip(&peer->defaddr, v->value)) { 16081 ASTOBJ_UNREF(peer, sip_destroy_peer); 16082 return NULL; 16083 } 16084 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 16085 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 16086 } else if (!strcasecmp(v->name, "port")) { 16087 if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) 16088 peer->defaddr.sin_port = htons(atoi(v->value)); 16089 else 16090 peer->addr.sin_port = htons(atoi(v->value)); 16091 } else if (!strcasecmp(v->name, "callingpres")) { 16092 peer->callingpres = ast_parse_caller_presentation(v->value); 16093 if (peer->callingpres == -1) 16094 peer->callingpres = atoi(v->value); 16095 } else if (!strcasecmp(v->name, "username")) { 16096 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 16097 } else if (!strcasecmp(v->name, "language")) { 16098 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 16099 } else if (!strcasecmp(v->name, "regexten")) { 16100 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 16101 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 16102 peer->call_limit = atoi(v->value); 16103 if (peer->call_limit < 0) 16104 peer->call_limit = 0; 16105 } else if (!strcasecmp(v->name, "amaflags")) { 16106 format = ast_cdr_amaflags2int(v->value); 16107 if (format < 0) { 16108 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 16109 } else { 16110 peer->amaflags = format; 16111 } 16112 } else if (!strcasecmp(v->name, "accountcode")) { 16113 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 16114 } else if (!strcasecmp(v->name, "mohinterpret") 16115 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16116 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 16117 } else if (!strcasecmp(v->name, "mohsuggest")) { 16118 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 16119 } else if (!strcasecmp(v->name, "mailbox")) { 16120 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 16121 } else if (!strcasecmp(v->name, "subscribemwi")) { 16122 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 16123 } else if (!strcasecmp(v->name, "vmexten")) { 16124 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 16125 } else if (!strcasecmp(v->name, "callgroup")) { 16126 peer->callgroup = ast_get_group(v->value); 16127 } else if (!strcasecmp(v->name, "allowtransfer")) { 16128 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16129 } else if (!strcasecmp(v->name, "pickupgroup")) { 16130 peer->pickupgroup = ast_get_group(v->value); 16131 } else if (!strcasecmp(v->name, "allow")) { 16132 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 16133 } else if (!strcasecmp(v->name, "disallow")) { 16134 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 16135 } else if (!strcasecmp(v->name, "autoframing")) { 16136 peer->autoframing = ast_true(v->value); 16137 } else if (!strcasecmp(v->name, "rtptimeout")) { 16138 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 16139 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16140 peer->rtptimeout = global_rtptimeout; 16141 } 16142 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 16143 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 16144 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16145 peer->rtpholdtimeout = global_rtpholdtimeout; 16146 } 16147 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 16148 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 16149 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 16150 peer->rtpkeepalive = global_rtpkeepalive; 16151 } 16152 } else if (!strcasecmp(v->name, "setvar")) { 16153 /* Set peer channel variable */ 16154 varname = ast_strdupa(v->value); 16155 if ((varval = strchr(varname, '='))) { 16156 *varval++ = '\0'; 16157 if ((tmpvar = ast_variable_new(varname, varval))) { 16158 tmpvar->next = peer->chanvars; 16159 peer->chanvars = tmpvar; 16160 } 16161 } 16162 } else if (!strcasecmp(v->name, "qualify")) { 16163 if (!strcasecmp(v->value, "no")) { 16164 peer->maxms = 0; 16165 } else if (!strcasecmp(v->value, "yes")) { 16166 peer->maxms = DEFAULT_MAXMS; 16167 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 16168 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); 16169 peer->maxms = 0; 16170 } 16171 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16172 peer->maxcallbitrate = atoi(v->value); 16173 if (peer->maxcallbitrate < 0) 16174 peer->maxcallbitrate = default_maxcallbitrate; 16175 } 16176 } 16177 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) { 16178 time_t nowtime = time(NULL); 16179 16180 if ((nowtime - regseconds) > 0) { 16181 destroy_association(peer); 16182 memset(&peer->addr, 0, sizeof(peer->addr)); 16183 if (option_debug) 16184 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 16185 } 16186 } 16187 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 16188 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 16189 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 16190 global_allowsubscribe = TRUE; /* No global ban any more */ 16191 if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME)) 16192 reg_source_db(peer); 16193 ASTOBJ_UNMARK(peer); 16194 ast_free_ha(oldha); 16195 return peer; 16196 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 11192 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().
11193 { 11194 char a1[256]; 11195 char a2[256]; 11196 char a1_hash[256]; 11197 char a2_hash[256]; 11198 char resp[256]; 11199 char resp_hash[256]; 11200 char uri[256]; 11201 char cnonce[80]; 11202 const char *username; 11203 const char *secret; 11204 const char *md5secret; 11205 struct sip_auth *auth = NULL; /* Realm authentication */ 11206 11207 if (!ast_strlen_zero(p->domain)) 11208 ast_copy_string(uri, p->domain, sizeof(uri)); 11209 else if (!ast_strlen_zero(p->uri)) 11210 ast_copy_string(uri, p->uri, sizeof(uri)); 11211 else 11212 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr)); 11213 11214 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 11215 11216 /* Check if we have separate auth credentials */ 11217 if ((auth = find_realm_authentication(authl, p->realm))) { 11218 ast_log(LOG_WARNING, "use realm [%s] from peer [%s][%s]\n", 11219 auth->username, p->peername, p->username); 11220 username = auth->username; 11221 secret = auth->secret; 11222 md5secret = auth->md5secret; 11223 if (sipdebug) 11224 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 11225 } else { 11226 /* No authentication, use peer or register= config */ 11227 username = p->authname; 11228 secret = p->peersecret; 11229 md5secret = p->peermd5secret; 11230 } 11231 if (ast_strlen_zero(username)) /* We have no authentication */ 11232 return -1; 11233 11234 /* Calculate SIP digest response */ 11235 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 11236 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 11237 if (!ast_strlen_zero(md5secret)) 11238 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 11239 else 11240 ast_md5_hash(a1_hash,a1); 11241 ast_md5_hash(a2_hash,a2); 11242 11243 p->noncecount++; 11244 if (!ast_strlen_zero(p->qop)) 11245 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 11246 else 11247 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 11248 ast_md5_hash(resp_hash, resp); 11249 /* XXX We hard code our qop to "auth" for now. XXX */ 11250 if (!ast_strlen_zero(p->qop)) 11251 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); 11252 else 11253 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); 11254 11255 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 11256 11257 return 0; 11258 }
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 7938 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().
07939 { 07940 struct sip_route *thishop, *head, *tail; 07941 int start = 0; 07942 int len; 07943 const char *rr, *contact, *c; 07944 07945 /* Once a persistant route is set, don't fool with it */ 07946 if (p->route && p->route_persistant) { 07947 if (option_debug) 07948 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 07949 return; 07950 } 07951 07952 if (p->route) { 07953 free_old_route(p->route); 07954 p->route = NULL; 07955 } 07956 07957 p->route_persistant = backwards; 07958 07959 /* Build a tailq, then assign it to p->route when done. 07960 * If backwards, we add entries from the head so they end up 07961 * in reverse order. However, we do need to maintain a correct 07962 * tail pointer because the contact is always at the end. 07963 */ 07964 head = NULL; 07965 tail = head; 07966 /* 1st we pass through all the hops in any Record-Route headers */ 07967 for (;;) { 07968 /* Each Record-Route header */ 07969 rr = __get_header(req, "Record-Route", &start); 07970 if (*rr == '\0') 07971 break; 07972 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 07973 ++rr; 07974 len = strcspn(rr, ">") + 1; 07975 /* Make a struct route */ 07976 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 07977 /* ast_calloc is not needed because all fields are initialized in this block */ 07978 ast_copy_string(thishop->hop, rr, len); 07979 if (option_debug > 1) 07980 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 07981 /* Link in */ 07982 if (backwards) { 07983 /* Link in at head so they end up in reverse order */ 07984 thishop->next = head; 07985 head = thishop; 07986 /* If this was the first then it'll be the tail */ 07987 if (!tail) 07988 tail = thishop; 07989 } else { 07990 thishop->next = NULL; 07991 /* Link in at the end */ 07992 if (tail) 07993 tail->next = thishop; 07994 else 07995 head = thishop; 07996 tail = thishop; 07997 } 07998 } 07999 } 08000 } 08001 08002 /* Only append the contact if we are dealing with a strict router */ 08003 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 08004 /* 2nd append the Contact: if there is one */ 08005 /* Can be multiple Contact headers, comma separated values - we just take the first */ 08006 contact = get_header(req, "Contact"); 08007 if (!ast_strlen_zero(contact)) { 08008 if (option_debug > 1) 08009 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 08010 /* Look for <: delimited address */ 08011 c = strchr(contact, '<'); 08012 if (c) { 08013 /* Take to > */ 08014 ++c; 08015 len = strcspn(c, ">") + 1; 08016 } else { 08017 /* No <> - just take the lot */ 08018 c = contact; 08019 len = strlen(contact) + 1; 08020 } 08021 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08022 /* ast_calloc is not needed because all fields are initialized in this block */ 08023 ast_copy_string(thishop->hop, c, len); 08024 thishop->next = NULL; 08025 /* Goes at the end */ 08026 if (tail) 08027 tail->next = thishop; 08028 else 08029 head = thishop; 08030 } 08031 } 08032 } 08033 08034 /* Store as new route */ 08035 p->route = head; 08036 08037 /* For debugging dump what we ended up with */ 08038 if (sip_debug_test_pvt(p)) 08039 list_route(p->route); 08040 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 6569 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().
06570 { 06571 int send_pres_tags = TRUE; 06572 const char *privacy=NULL; 06573 const char *screen=NULL; 06574 char buf[256]; 06575 const char *clid = default_callerid; 06576 const char *clin = NULL; 06577 const char *fromdomain; 06578 06579 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 06580 return; 06581 06582 if (p->owner && p->owner->cid.cid_num) 06583 clid = p->owner->cid.cid_num; 06584 if (p->owner && p->owner->cid.cid_name) 06585 clin = p->owner->cid.cid_name; 06586 if (ast_strlen_zero(clin)) 06587 clin = clid; 06588 06589 switch (p->callingpres) { 06590 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 06591 privacy = "off"; 06592 screen = "no"; 06593 break; 06594 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 06595 privacy = "off"; 06596 screen = "yes"; 06597 break; 06598 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 06599 privacy = "off"; 06600 screen = "no"; 06601 break; 06602 case AST_PRES_ALLOWED_NETWORK_NUMBER: 06603 privacy = "off"; 06604 screen = "yes"; 06605 break; 06606 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 06607 privacy = "full"; 06608 screen = "no"; 06609 break; 06610 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 06611 privacy = "full"; 06612 screen = "yes"; 06613 break; 06614 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 06615 privacy = "full"; 06616 screen = "no"; 06617 break; 06618 case AST_PRES_PROHIB_NETWORK_NUMBER: 06619 privacy = "full"; 06620 screen = "yes"; 06621 break; 06622 case AST_PRES_NUMBER_NOT_AVAILABLE: 06623 send_pres_tags = FALSE; 06624 break; 06625 default: 06626 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 06627 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 06628 privacy = "full"; 06629 else 06630 privacy = "off"; 06631 screen = "no"; 06632 break; 06633 } 06634 06635 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 06636 06637 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 06638 if (send_pres_tags) 06639 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 06640 ast_string_field_set(p, rpid, buf); 06641 06642 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 06643 S_OR(p->fromuser, clid), 06644 fromdomain, p->tag); 06645 }
static struct sip_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
int | realtime | |||
) | [static] |
Initiate a SIP user structure from configuration (configuration or realtime).
Definition at line 15774 of file chan_sip.c.
References sip_user::allowtransfer, ast_append_ha(), ast_calloc, ast_copy_flags, ast_strdupa, ast_true(), ast_variable_new(), ASTOBJ_INIT, sip_user::chanvars, default_prefs, format, global_flags, sip_user::ha, handle_common_options(), ast_variable::name, ast_variable::next, sip_user::secret, SIP_FLAGS_TO_COPY, SIP_PAGE2_FLAGS_TO_COPY, TRANSFER_CLOSED, TRANSFER_OPENFORALL, and ast_variable::value.
15775 { 15776 struct sip_user *user; 15777 int format; 15778 struct ast_ha *oldha = NULL; 15779 char *varname = NULL, *varval = NULL; 15780 struct ast_variable *tmpvar = NULL; 15781 struct ast_flags userflags[2] = {{(0)}}; 15782 struct ast_flags mask[2] = {{(0)}}; 15783 15784 15785 if (!(user = ast_calloc(1, sizeof(*user)))) 15786 return NULL; 15787 15788 suserobjs++; 15789 ASTOBJ_INIT(user); 15790 ast_copy_string(user->name, name, sizeof(user->name)); 15791 oldha = user->ha; 15792 user->ha = NULL; 15793 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 15794 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 15795 user->capability = global_capability; 15796 user->allowtransfer = global_allowtransfer; 15797 user->maxcallbitrate = default_maxcallbitrate; 15798 user->autoframing = global_autoframing; 15799 user->prefs = default_prefs; 15800 /* set default context */ 15801 strcpy(user->context, default_context); 15802 strcpy(user->language, default_language); 15803 strcpy(user->mohinterpret, default_mohinterpret); 15804 strcpy(user->mohsuggest, default_mohsuggest); 15805 for (; v; v = v->next) { 15806 if (handle_common_options(&userflags[0], &mask[0], v)) 15807 continue; 15808 15809 if (!strcasecmp(v->name, "context")) { 15810 ast_copy_string(user->context, v->value, sizeof(user->context)); 15811 } else if (!strcasecmp(v->name, "subscribecontext")) { 15812 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 15813 } else if (!strcasecmp(v->name, "setvar")) { 15814 varname = ast_strdupa(v->value); 15815 if ((varval = strchr(varname,'='))) { 15816 *varval++ = '\0'; 15817 if ((tmpvar = ast_variable_new(varname, varval))) { 15818 tmpvar->next = user->chanvars; 15819 user->chanvars = tmpvar; 15820 } 15821 } 15822 } else if (!strcasecmp(v->name, "permit") || 15823 !strcasecmp(v->name, "deny")) { 15824 user->ha = ast_append_ha(v->name, v->value, user->ha); 15825 } else if (!strcasecmp(v->name, "allowtransfer")) { 15826 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 15827 } else if (!strcasecmp(v->name, "secret")) { 15828 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 15829 } else if (!strcasecmp(v->name, "md5secret")) { 15830 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 15831 } else if (!strcasecmp(v->name, "callerid")) { 15832 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 15833 } else if (!strcasecmp(v->name, "fullname")) { 15834 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 15835 } else if (!strcasecmp(v->name, "cid_number")) { 15836 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 15837 } else if (!strcasecmp(v->name, "callgroup")) { 15838 user->callgroup = ast_get_group(v->value); 15839 } else if (!strcasecmp(v->name, "pickupgroup")) { 15840 user->pickupgroup = ast_get_group(v->value); 15841 } else if (!strcasecmp(v->name, "language")) { 15842 ast_copy_string(user->language, v->value, sizeof(user->language)); 15843 } else if (!strcasecmp(v->name, "mohinterpret") 15844 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 15845 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 15846 } else if (!strcasecmp(v->name, "mohsuggest")) { 15847 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 15848 } else if (!strcasecmp(v->name, "accountcode")) { 15849 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 15850 } else if (!strcasecmp(v->name, "call-limit")) { 15851 user->call_limit = atoi(v->value); 15852 if (user->call_limit < 0) 15853 user->call_limit = 0; 15854 } else if (!strcasecmp(v->name, "amaflags")) { 15855 format = ast_cdr_amaflags2int(v->value); 15856 if (format < 0) { 15857 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 15858 } else { 15859 user->amaflags = format; 15860 } 15861 } else if (!strcasecmp(v->name, "allow")) { 15862 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 15863 } else if (!strcasecmp(v->name, "disallow")) { 15864 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 15865 } else if (!strcasecmp(v->name, "autoframing")) { 15866 user->autoframing = ast_true(v->value); 15867 } else if (!strcasecmp(v->name, "callingpres")) { 15868 user->callingpres = ast_parse_caller_presentation(v->value); 15869 if (user->callingpres == -1) 15870 user->callingpres = atoi(v->value); 15871 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 15872 user->maxcallbitrate = atoi(v->value); 15873 if (user->maxcallbitrate < 0) 15874 user->maxcallbitrate = default_maxcallbitrate; 15875 } 15876 /* We can't just report unknown options here because this may be a 15877 * type=friend entry. All user options are valid for a peer, but not 15878 * the other way around. */ 15879 } 15880 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 15881 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 15882 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 15883 global_allowsubscribe = TRUE; /* No global ban any more */ 15884 ast_free_ha(oldha); 15885 return user; 15886 }
static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 1761 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().
01762 { 01763 /* Work around buggy UNIDEN UIP200 firmware */ 01764 const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : ""; 01765 01766 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01767 ast_string_field_build(p, via, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s", 01768 ast_inet_ntoa(p->ourip), ourport, p->branch, rport); 01769 }
static int cb_extensionstate | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 8230 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_verbose(), sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::laststate, 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().
08231 { 08232 struct sip_pvt *p = data; 08233 08234 switch(state) { 08235 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 08236 case AST_EXTENSION_REMOVED: /* Extension is gone */ 08237 if (p->autokillid > -1) 08238 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 08239 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 08240 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); 08241 p->stateid = -1; 08242 p->subscribed = NONE; 08243 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 08244 break; 08245 default: /* Tell user */ 08246 p->laststate = state; 08247 break; 08248 } 08249 if (p->subscribed != NONE) /* Only send state NOTIFY if we know the format */ 08250 transmit_state_notify(p, state, 1, FALSE); 08251 08252 if (option_verbose > 1) 08253 ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username); 08254 return 0; 08255 }
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 8048 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().
08051 { 08052 const char *response = "407 Proxy Authentication Required"; 08053 const char *reqheader = "Proxy-Authorization"; 08054 const char *respheader = "Proxy-Authenticate"; 08055 const char *authtoken; 08056 char a1_hash[256]; 08057 char resp_hash[256]=""; 08058 char tmp[BUFSIZ * 2]; /* Make a large enough buffer */ 08059 char *c; 08060 int wrongnonce = FALSE; 08061 int good_response; 08062 const char *usednonce = p->randdata; 08063 08064 /* table of recognised keywords, and their value in the digest */ 08065 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 08066 struct x { 08067 const char *key; 08068 const char *s; 08069 } *i, keys[] = { 08070 [K_RESP] = { "response=", "" }, 08071 [K_URI] = { "uri=", "" }, 08072 [K_USER] = { "username=", "" }, 08073 [K_NONCE] = { "nonce=", "" }, 08074 [K_LAST] = { NULL, NULL} 08075 }; 08076 08077 /* Always OK if no secret */ 08078 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 08079 return AUTH_SUCCESSFUL; 08080 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 08081 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 08082 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 08083 different circumstances! What a surprise. */ 08084 response = "401 Unauthorized"; 08085 reqheader = "Authorization"; 08086 respheader = "WWW-Authenticate"; 08087 } 08088 authtoken = get_header(req, reqheader); 08089 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 08090 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 08091 information */ 08092 if (!reliable) { 08093 /* Resend message if this was NOT a reliable delivery. Otherwise the 08094 retransmission should get it */ 08095 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08096 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 08097 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08098 } 08099 return AUTH_CHALLENGE_SENT; 08100 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 08101 /* We have no auth, so issue challenge and request authentication */ 08102 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08103 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08104 /* Schedule auto destroy in 32 seconds */ 08105 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08106 return AUTH_CHALLENGE_SENT; 08107 } 08108 08109 /* --- We have auth, so check it */ 08110 08111 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 08112 an example in the spec of just what it is you're doing a hash on. */ 08113 08114 08115 /* Make a copy of the response and parse it */ 08116 ast_copy_string(tmp, authtoken, sizeof(tmp)); 08117 c = tmp; 08118 08119 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 08120 for (i = keys; i->key != NULL; i++) { 08121 const char *separator = ","; /* default */ 08122 08123 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 08124 continue; 08125 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08126 c += strlen(i->key); 08127 if (*c == '"') { /* in quotes. Skip first and look for last */ 08128 c++; 08129 separator = "\""; 08130 } 08131 i->s = c; 08132 strsep(&c, separator); 08133 break; 08134 } 08135 if (i->key == NULL) /* not found, jump after space or comma */ 08136 strsep(&c, " ,"); 08137 } 08138 08139 /* Verify that digest username matches the username we auth as */ 08140 if (strcmp(username, keys[K_USER].s)) { 08141 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 08142 username, keys[K_USER].s); 08143 /* Oops, we're trying something here */ 08144 return AUTH_USERNAME_MISMATCH; 08145 } 08146 08147 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 08148 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */ 08149 wrongnonce = TRUE; 08150 usednonce = keys[K_NONCE].s; 08151 } 08152 08153 if (!ast_strlen_zero(md5secret)) 08154 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 08155 else { 08156 char a1[256]; 08157 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 08158 ast_md5_hash(a1_hash, a1); 08159 } 08160 08161 /* compute the expected response to compare with what we received */ 08162 { 08163 char a2[256]; 08164 char a2_hash[256]; 08165 char resp[256]; 08166 08167 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 08168 S_OR(keys[K_URI].s, uri)); 08169 ast_md5_hash(a2_hash, a2); 08170 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 08171 ast_md5_hash(resp_hash, resp); 08172 } 08173 08174 good_response = keys[K_RESP].s && 08175 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 08176 if (wrongnonce) { 08177 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08178 if (good_response) { 08179 if (sipdebug) 08180 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To")); 08181 /* We got working auth token, based on stale nonce . */ 08182 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 08183 } else { 08184 /* Everything was wrong, so give the device one more try with a new challenge */ 08185 if (sipdebug) 08186 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 08187 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 08188 } 08189 08190 /* Schedule auto destroy in 32 seconds */ 08191 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08192 return AUTH_CHALLENGE_SENT; 08193 } 08194 if (good_response) { 08195 append_history(p, "AuthOK", "Auth challenge succesful for %s", username); 08196 return AUTH_SUCCESSFUL; 08197 } 08198 08199 /* Ok, we have a bad username/secret pair */ 08200 /* Challenge again, and again, and again */ 08201 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08202 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08203 08204 return AUTH_CHALLENGE_SENT; 08205 }
static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 11646 of file chan_sip.c.
References ast_clear_flag, ast_log(), ast_test_flag, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, LOG_DEBUG, option_debug, SIP_BYE, SIP_CANCEL, SIP_NEEDREINVITE, SIP_PENDINGBYE, sip_scheddestroy(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), TRUE, and XMIT_RELIABLE.
Referenced by handle_request(), and handle_response_invite().
11647 { 11648 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 11649 /* if we can't BYE, then this is really a pending CANCEL */ 11650 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) 11651 transmit_request(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE); 11652 /* Actually don't destroy us yet, wait for the 487 on our original 11653 INVITE, but do set an autodestruct just in case we never get it. */ 11654 else 11655 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 11656 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 11657 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11658 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 11659 if (option_debug) 11660 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 11661 /* Didn't get to reinvite yet, so do it now */ 11662 transmit_reinvite_with_sdp(p); 11663 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 11664 } 11665 }
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 15653 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, domain::domain, and result.
Referenced by func_check_sipdomain(), get_destination(), handle_request_refer(), and register_verify().
15654 { 15655 struct domain *d; 15656 int result = 0; 15657 15658 AST_LIST_LOCK(&domain_list); 15659 AST_LIST_TRAVERSE(&domain_list, d, list) { 15660 if (strcasecmp(d->domain, domain)) 15661 continue; 15662 15663 if (len && !ast_strlen_zero(d->context)) 15664 ast_copy_string(context, d->context, len); 15665 15666 result = 1; 15667 break; 15668 } 15669 AST_LIST_UNLOCK(&domain_list); 15670 15671 return result; 15672 }
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 9302 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
09303 { 09304 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 09305 }
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 8988 of file chan_sip.c.
References sip_peer::accountcode, sip_user::accountcode, accountcode, sip_user::allowtransfer, sip_peer::amaflags, sip_user::amaflags, ast_apply_ha(), ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_is_shrinkable_phonenumber(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_variable_new(), ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, AUTH_FAKE_AUTH, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, sip_peer::autoframing, sip_user::autoframing, build_contact(), sip_peer::call_limit, sip_user::call_limit, sip_peer::callgroup, sip_user::callgroup, sip_peer::callingpres, sip_user::callingpres, sip_peer::capability, sip_user::capability, sip_peer::chanvars, sip_user::chanvars, check_auth(), sip_peer::cid_name, sip_user::cid_name, cid_name, sip_peer::cid_num, sip_user::cid_num, cid_num, sip_peer::context, context, sip_user::context, debug, do_setnat(), exten, find_peer(), find_user(), sip_peer::flags, sip_user::flags, sip_peer::fullcontact, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), sip_user::ha, sip_peer::language, sip_user::language, language, sip_peer::lastms, LOG_NOTICE, sip_peer::maxcallbitrate, sip_user::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_user::md5secret, sip_peer::mohinterpret, sip_user::mohinterpret, mohinterpret, sip_peer::mohsuggest, sip_user::mohsuggest, mohsuggest, ast_variable::next, sip_peer::pickupgroup, sip_user::pickupgroup, sip_peer::prefs, sip_user::prefs, sip_peer::secret, sip_user::secret, SIP_CALL_LIMIT, sip_cancel_destroy(), sip_debug_test_addr(), sip_destroy_peer(), sip_destroy_user(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_INSECURE_INVITE, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_VIDEOSUPPORT, SIP_PKT_IGNORE, SIP_SUBSCRIBE, SIP_TRUSTRPID, sip_peer::sipoptions, sip_user::sipoptions, strsep(), sip_peer::subscribecontext, sip_user::subscribecontext, t, sip_peer::username, and username.
Referenced by check_user(), and handle_request_subscribe().
08991 { 08992 struct sip_user *user = NULL; 08993 struct sip_peer *peer; 08994 char from[256], *c; 08995 char *of; 08996 char rpid_num[50]; 08997 const char *rpid; 08998 enum check_auth_result res = AUTH_SUCCESSFUL; 08999 char *t; 09000 char calleridname[50]; 09001 int debug=sip_debug_test_addr(sin); 09002 struct ast_variable *tmpvar = NULL, *v = NULL; 09003 char *uri2 = ast_strdupa(uri); 09004 09005 /* Terminate URI */ 09006 t = uri2; 09007 while (*t && *t > 32 && *t != ';') 09008 t++; 09009 *t = '\0'; 09010 ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */ 09011 if (pedanticsipchecking) 09012 ast_uri_decode(from); 09013 /* XXX here tries to map the username for invite things */ 09014 memset(calleridname, 0, sizeof(calleridname)); 09015 get_calleridname(from, calleridname, sizeof(calleridname)); 09016 if (calleridname[0]) 09017 ast_string_field_set(p, cid_name, calleridname); 09018 09019 rpid = get_header(req, "Remote-Party-ID"); 09020 memset(rpid_num, 0, sizeof(rpid_num)); 09021 if (!ast_strlen_zero(rpid)) 09022 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 09023 09024 of = get_in_brackets(from); 09025 if (ast_strlen_zero(p->exten)) { 09026 t = uri2; 09027 if (!strncmp(t, "sip:", 4)) 09028 t+= 4; 09029 ast_string_field_set(p, exten, t); 09030 t = strchr(p->exten, '@'); 09031 if (t) 09032 *t = '\0'; 09033 if (ast_strlen_zero(p->our_contact)) 09034 build_contact(p); 09035 } 09036 /* save the URI part of the From header */ 09037 ast_string_field_set(p, from, of); 09038 if (strncmp(of, "sip:", 4)) { 09039 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 09040 } else 09041 of += 4; 09042 /* Get just the username part */ 09043 if ((c = strchr(of, '@'))) { 09044 char *tmp; 09045 *c = '\0'; 09046 if ((c = strchr(of, ':'))) 09047 *c = '\0'; 09048 tmp = ast_strdupa(of); 09049 /* We need to be able to handle auth-headers looking like 09050 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 09051 */ 09052 tmp = strsep(&tmp, ";"); 09053 if (ast_is_shrinkable_phonenumber(tmp)) 09054 ast_shrink_phone_number(tmp); 09055 ast_string_field_set(p, cid_num, tmp); 09056 } 09057 if (ast_strlen_zero(of)) 09058 return AUTH_SUCCESSFUL; 09059 09060 if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */ 09061 user = find_user(of, 1); 09062 09063 /* Find user based on user name in the from header */ 09064 if (user && ast_apply_ha(user->ha, sin)) { 09065 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09066 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09067 /* copy channel vars */ 09068 for (v = user->chanvars ; v ; v = v->next) { 09069 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09070 tmpvar->next = p->chanvars; 09071 p->chanvars = tmpvar; 09072 } 09073 } 09074 p->prefs = user->prefs; 09075 /* Set Frame packetization */ 09076 if (p->rtp) { 09077 ast_rtp_codec_setpref(p->rtp, &p->prefs); 09078 p->autoframing = user->autoframing; 09079 } 09080 /* replace callerid if rpid found, and not restricted */ 09081 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09082 char *tmp; 09083 if (*calleridname) 09084 ast_string_field_set(p, cid_name, calleridname); 09085 tmp = ast_strdupa(rpid_num); 09086 if (ast_is_shrinkable_phonenumber(tmp)) 09087 ast_shrink_phone_number(tmp); 09088 ast_string_field_set(p, cid_num, tmp); 09089 } 09090 09091 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 09092 09093 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09094 sip_cancel_destroy(p); 09095 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09096 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09097 /* Copy SIP extensions profile from INVITE */ 09098 if (p->sipoptions) 09099 user->sipoptions = p->sipoptions; 09100 09101 /* If we have a call limit, set flag */ 09102 if (user->call_limit) 09103 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09104 if (!ast_strlen_zero(user->context)) 09105 ast_string_field_set(p, context, user->context); 09106 if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num)) { 09107 char *tmp = ast_strdupa(user->cid_num); 09108 if (ast_is_shrinkable_phonenumber(tmp)) 09109 ast_shrink_phone_number(tmp); 09110 ast_string_field_set(p, cid_num, tmp); 09111 } 09112 if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num)) 09113 ast_string_field_set(p, cid_name, user->cid_name); 09114 ast_string_field_set(p, username, user->name); 09115 ast_string_field_set(p, peername, user->name); 09116 ast_string_field_set(p, peersecret, user->secret); 09117 ast_string_field_set(p, peermd5secret, user->md5secret); 09118 ast_string_field_set(p, subscribecontext, user->subscribecontext); 09119 ast_string_field_set(p, accountcode, user->accountcode); 09120 ast_string_field_set(p, language, user->language); 09121 ast_string_field_set(p, mohsuggest, user->mohsuggest); 09122 ast_string_field_set(p, mohinterpret, user->mohinterpret); 09123 p->allowtransfer = user->allowtransfer; 09124 p->amaflags = user->amaflags; 09125 p->callgroup = user->callgroup; 09126 p->pickupgroup = user->pickupgroup; 09127 if (user->callingpres) /* User callingpres setting will override RPID header */ 09128 p->callingpres = user->callingpres; 09129 09130 /* Set default codec settings for this call */ 09131 p->capability = user->capability; /* User codec choice */ 09132 p->jointcapability = user->capability; /* Our codecs */ 09133 if (p->peercapability) /* AND with peer's codecs */ 09134 p->jointcapability &= p->peercapability; 09135 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09136 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09137 p->noncodeccapability |= AST_RTP_DTMF; 09138 else 09139 p->noncodeccapability &= ~AST_RTP_DTMF; 09140 p->jointnoncodeccapability = p->noncodeccapability; 09141 if (p->t38.peercapability) 09142 p->t38.jointcapability &= p->t38.peercapability; 09143 p->maxcallbitrate = user->maxcallbitrate; 09144 /* If we do not support video, remove video from call structure */ 09145 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09146 ast_rtp_destroy(p->vrtp); 09147 p->vrtp = NULL; 09148 } 09149 } 09150 if (user && debug) 09151 ast_verbose("Found user '%s'\n", user->name); 09152 } else { 09153 if (user) { 09154 if (!authpeer && debug) 09155 ast_verbose("Found user '%s', but fails host access\n", user->name); 09156 ASTOBJ_UNREF(user,sip_destroy_user); 09157 } 09158 user = NULL; 09159 } 09160 09161 if (!user) { 09162 /* If we didn't find a user match, check for peers */ 09163 if (sipmethod == SIP_SUBSCRIBE) 09164 /* For subscribes, match on peer name only */ 09165 peer = find_peer(of, NULL, 1); 09166 else 09167 /* Look for peer based on the IP address we received data from */ 09168 /* If peer is registered from this IP address or have this as a default 09169 IP address, this call is from the peer 09170 */ 09171 peer = find_peer(NULL, &p->recv, 1); 09172 09173 if (peer) { 09174 /* Set Frame packetization */ 09175 if (p->rtp) { 09176 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09177 p->autoframing = peer->autoframing; 09178 } 09179 if (debug) 09180 ast_verbose("Found peer '%s'\n", peer->name); 09181 09182 /* Take the peer */ 09183 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09184 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09185 09186 /* Copy SIP extensions profile to peer */ 09187 if (p->sipoptions) 09188 peer->sipoptions = p->sipoptions; 09189 09190 /* replace callerid if rpid found, and not restricted */ 09191 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09192 char *tmp = ast_strdupa(rpid_num); 09193 if (*calleridname) 09194 ast_string_field_set(p, cid_name, calleridname); 09195 if (ast_is_shrinkable_phonenumber(tmp)) 09196 ast_shrink_phone_number(tmp); 09197 ast_string_field_set(p, cid_num, tmp); 09198 } 09199 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 09200 09201 ast_string_field_set(p, peersecret, peer->secret); 09202 ast_string_field_set(p, peermd5secret, peer->md5secret); 09203 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 09204 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 09205 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 09206 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 09207 p->callingpres = peer->callingpres; 09208 if (peer->maxms && peer->lastms) 09209 p->timer_t1 = peer->lastms; 09210 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 09211 /* Pretend there is no required authentication */ 09212 ast_string_field_free(p, peersecret); 09213 ast_string_field_free(p, peermd5secret); 09214 } 09215 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09216 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09217 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09218 /* If we have a call limit, set flag */ 09219 if (peer->call_limit) 09220 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09221 ast_string_field_set(p, peername, peer->name); 09222 ast_string_field_set(p, authname, peer->name); 09223 09224 /* copy channel vars */ 09225 for (v = peer->chanvars ; v ; v = v->next) { 09226 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09227 tmpvar->next = p->chanvars; 09228 p->chanvars = tmpvar; 09229 } 09230 } 09231 if (authpeer) { 09232 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 09233 } 09234 09235 if (!ast_strlen_zero(peer->username)) { 09236 ast_string_field_set(p, username, peer->username); 09237 /* Use the default username for authentication on outbound calls */ 09238 /* XXX this takes the name from the caller... can we override ? */ 09239 ast_string_field_set(p, authname, peer->username); 09240 } 09241 if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num)) { 09242 char *tmp = ast_strdupa(peer->cid_num); 09243 if (ast_is_shrinkable_phonenumber(tmp)) 09244 ast_shrink_phone_number(tmp); 09245 ast_string_field_set(p, cid_num, tmp); 09246 } 09247 if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) 09248 ast_string_field_set(p, cid_name, peer->cid_name); 09249 ast_string_field_set(p, fullcontact, peer->fullcontact); 09250 if (!ast_strlen_zero(peer->context)) 09251 ast_string_field_set(p, context, peer->context); 09252 ast_string_field_set(p, peersecret, peer->secret); 09253 ast_string_field_set(p, peermd5secret, peer->md5secret); 09254 ast_string_field_set(p, language, peer->language); 09255 ast_string_field_set(p, accountcode, peer->accountcode); 09256 p->amaflags = peer->amaflags; 09257 p->callgroup = peer->callgroup; 09258 p->pickupgroup = peer->pickupgroup; 09259 p->capability = peer->capability; 09260 p->prefs = peer->prefs; 09261 p->jointcapability = peer->capability; 09262 if (p->peercapability) 09263 p->jointcapability &= p->peercapability; 09264 p->maxcallbitrate = peer->maxcallbitrate; 09265 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09266 ast_rtp_destroy(p->vrtp); 09267 p->vrtp = NULL; 09268 } 09269 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09270 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09271 p->noncodeccapability |= AST_RTP_DTMF; 09272 else 09273 p->noncodeccapability &= ~AST_RTP_DTMF; 09274 p->jointnoncodeccapability = p->noncodeccapability; 09275 if (p->t38.peercapability) 09276 p->t38.jointcapability &= p->t38.peercapability; 09277 } 09278 ASTOBJ_UNREF(peer, sip_destroy_peer); 09279 } else { 09280 if (debug) 09281 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 09282 09283 /* do we allow guests? */ 09284 if (!global_allowguest) { 09285 if (global_alwaysauthreject) 09286 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 09287 else 09288 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 09289 } 09290 } 09291 09292 } 09293 09294 if (user) 09295 ASTOBJ_UNREF(user, sip_destroy_user); 09296 return res; 09297 }
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 8856 of file chan_sip.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_verbose(), sip_pvt::flags, get_header(), hp, 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().
08857 { 08858 char via[256]; 08859 char *c, *pt; 08860 struct hostent *hp; 08861 struct ast_hostent ahp; 08862 08863 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 08864 08865 /* Work on the leftmost value of the topmost Via header */ 08866 c = strchr(via, ','); 08867 if (c) 08868 *c = '\0'; 08869 08870 /* Check for rport */ 08871 c = strstr(via, ";rport"); 08872 if (c && (c[6] != '=')) /* rport query, not answer */ 08873 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 08874 08875 c = strchr(via, ';'); 08876 if (c) 08877 *c = '\0'; 08878 08879 c = strchr(via, ' '); 08880 if (c) { 08881 *c = '\0'; 08882 c = ast_skip_blanks(c+1); 08883 if (strcasecmp(via, "SIP/2.0/UDP")) { 08884 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 08885 return; 08886 } 08887 pt = strchr(c, ':'); 08888 if (pt) 08889 *pt++ = '\0'; /* remember port pointer */ 08890 hp = ast_gethostbyname(c, &ahp); 08891 if (!hp) { 08892 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 08893 return; 08894 } 08895 memset(&p->sa, 0, sizeof(p->sa)); 08896 p->sa.sin_family = AF_INET; 08897 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 08898 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 08899 08900 if (sip_debug_test_pvt(p)) { 08901 const struct sockaddr_in *dst = sip_real_dst(p); 08902 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 08903 } 08904 } 08905 }
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 9744 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), AST_MAX_CONTEXT, and strsep().
09745 { 09746 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 09747 09748 while ((oldcontext = strsep(&old, "&"))) { 09749 stalecontext = '\0'; 09750 ast_copy_string(newlist, new, sizeof(newlist)); 09751 stringp = newlist; 09752 while ((newcontext = strsep(&stringp, "&"))) { 09753 if (strcmp(newcontext, oldcontext) == 0) { 09754 /* This is not the context you're looking for */ 09755 stalecontext = '\0'; 09756 break; 09757 } else if (strcmp(newcontext, oldcontext)) { 09758 stalecontext = oldcontext; 09759 } 09760 09761 } 09762 if (stalecontext) 09763 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 09764 } 09765 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 15746 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by sip_destroy_peer(), sip_do_reload(), and unload_module().
15747 { 15748 struct sip_auth *a = authlist; 15749 struct sip_auth *b; 15750 15751 while (a) { 15752 b = a; 15753 a = a->next; 15754 free(b); 15755 } 15756 15757 return 1; 15758 }
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 15675 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().
15676 { 15677 struct domain *d; 15678 15679 AST_LIST_LOCK(&domain_list); 15680 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 15681 free(d); 15682 AST_LIST_UNLOCK(&domain_list); 15683 }
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 10557 of file chan_sip.c.
References complete_sip_peer().
10558 { 10559 if (pos == 3) 10560 return complete_sip_peer(word, state, 0); 10561 10562 return NULL; 10563 }
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 10531 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, peerl, and result.
Referenced by complete_sip_debug_peer(), complete_sip_prune_realtime_peer(), complete_sip_show_peer(), and complete_sipnotify().
10532 { 10533 char *result = NULL; 10534 int wordlen = strlen(word); 10535 int which = 0; 10536 10537 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 10538 /* locking of the object is not required because only the name and flags are being compared */ 10539 if (!strncasecmp(word, iterator->name, wordlen) && 10540 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 10541 ++which > state) 10542 result = ast_strdup(iterator->name); 10543 } while(0) ); 10544 return result; 10545 }
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 10625 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
10626 { 10627 if (pos == 4) 10628 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 10629 return NULL; 10630 }
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 10633 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
10634 { 10635 if (pos == 4) 10636 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 10637 10638 return NULL; 10639 }
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 10548 of file chan_sip.c.
References complete_sip_peer().
10549 { 10550 if (pos == 3) 10551 return complete_sip_peer(word, state, 0); 10552 10553 return NULL; 10554 }
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 10586 of file chan_sip.c.
References complete_sip_user().
10587 { 10588 if (pos == 3) 10589 return complete_sip_user(word, state, 0); 10590 10591 return NULL; 10592 }
static char * complete_sip_user | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on user name.
Definition at line 10566 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, result, and userl.
Referenced by complete_sip_prune_realtime_user(), and complete_sip_show_user().
10567 { 10568 char *result = NULL; 10569 int wordlen = strlen(word); 10570 int which = 0; 10571 10572 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 10573 /* locking of the object is not required because only the name and flags are being compared */ 10574 if (!strncasecmp(word, iterator->name, wordlen)) { 10575 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 10576 continue; 10577 if (++which > state) { 10578 result = ast_strdup(iterator->name); 10579 } 10580 } 10581 } while(0) ); 10582 return result; 10583 }
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 10512 of file chan_sip.c.
References ast_mutex_lock(), ast_strdup, iflist, and sip_pvt::next.
10513 { 10514 int which=0; 10515 struct sip_pvt *cur; 10516 char *c = NULL; 10517 int wordlen = strlen(word); 10518 10519 ast_mutex_lock(&iflock); 10520 for (cur = iflist; cur; cur = cur->next) { 10521 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 10522 c = ast_strdup(cur->callid); 10523 break; 10524 } 10525 } 10526 ast_mutex_unlock(&iflock); 10527 return c; 10528 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 10595 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
10596 { 10597 char *c = NULL; 10598 10599 if (pos == 2) { 10600 int which = 0; 10601 char *cat = NULL; 10602 int wordlen = strlen(word); 10603 10604 /* do completion for notify type */ 10605 10606 if (!notify_types) 10607 return NULL; 10608 10609 while ( (cat = ast_category_browse(notify_types, cat)) ) { 10610 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 10611 c = ast_strdup(cat); 10612 break; 10613 } 10614 } 10615 return c; 10616 } 10617 10618 if (pos > 2) 10619 return complete_sip_peer(word, state, 0); 10620 10621 return NULL; 10622 }
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 5380 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
05381 { 05382 int start = 0; 05383 int copied = 0; 05384 for (;;) { 05385 const char *tmp = __get_header(orig, field, &start); 05386 05387 if (ast_strlen_zero(tmp)) 05388 break; 05389 /* Add what we're responding to */ 05390 add_header(req, field, tmp); 05391 copied++; 05392 } 05393 return copied ? 0 : -1; 05394 }
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 5369 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
05370 { 05371 const char *tmp = get_header(orig, field); 05372 05373 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 05374 return add_header(req, field, tmp); 05375 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 05376 return -1; 05377 }
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 6414 of file chan_sip.c.
References offset.
Referenced by handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), initialize_initreq(), sip_park(), and sip_park_thread().
06415 { 06416 long offset; 06417 int x; 06418 offset = ((void *)dst) - ((void *)src); 06419 /* First copy stuff */ 06420 memcpy(dst, src, sizeof(*dst)); 06421 /* Now fix pointer arithmetic */ 06422 for (x=0; x < src->headers; x++) 06423 dst->header[x] += offset; 06424 for (x=0; x < src->lines; x++) 06425 dst->line[x] += offset; 06426 dst->rlPart1 += offset; 06427 dst->rlPart2 += offset; 06428 }
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 5402 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().
05403 { 05404 int copied = 0; 05405 int start = 0; 05406 05407 for (;;) { 05408 char new[256]; 05409 const char *oh = __get_header(orig, field, &start); 05410 05411 if (ast_strlen_zero(oh)) 05412 break; 05413 05414 if (!copied) { /* Only check for empty rport in topmost via header */ 05415 char leftmost[256], *others, *rport; 05416 05417 /* Only work on leftmost value */ 05418 ast_copy_string(leftmost, oh, sizeof(leftmost)); 05419 others = strchr(leftmost, ','); 05420 if (others) 05421 *others++ = '\0'; 05422 05423 /* Find ;rport; (empty request) */ 05424 rport = strstr(leftmost, ";rport"); 05425 if (rport && *(rport+6) == '=') 05426 rport = NULL; /* We already have a parameter to rport */ 05427 05428 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 05429 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 05430 /* We need to add received port - rport */ 05431 char *end; 05432 05433 rport = strstr(leftmost, ";rport"); 05434 05435 if (rport) { 05436 end = strchr(rport + 1, ';'); 05437 if (end) 05438 memmove(rport, end, strlen(end) + 1); 05439 else 05440 *rport = '\0'; 05441 } 05442 05443 /* Add rport to first VIA header if requested */ 05444 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 05445 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05446 ntohs(p->recv.sin_port), 05447 others ? "," : "", others ? others : ""); 05448 } else { 05449 /* We should *always* add a received to the topmost via */ 05450 snprintf(new, sizeof(new), "%s;received=%s%s%s", 05451 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05452 others ? "," : "", others ? others : ""); 05453 } 05454 oh = new; /* the header to copy */ 05455 } /* else add the following via headers untouched */ 05456 add_header(req, field, oh); 05457 copied++; 05458 } 05459 if (!copied) { 05460 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 05461 return -1; 05462 } 05463 return 0; 05464 }
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 2700 of file chan_sip.c.
References ahp, ast_get_srv(), ast_gethostbyname(), ast_log(), ast_string_field_set, ASTOBJ_UNREF, create_addr_from_peer(), find_peer(), hp, LOG_WARNING, portno, sip_pvt::recv, sip_pvt::sa, sip_destroy_peer(), STANDARD_SIP_PORT, sip_pvt::timer_t1, and sip_peer::tohost.
02701 { 02702 struct hostent *hp; 02703 struct ast_hostent ahp; 02704 struct sip_peer *p; 02705 char *port; 02706 int portno; 02707 char host[MAXHOSTNAMELEN], *hostn; 02708 char peer[256]; 02709 02710 ast_copy_string(peer, opeer, sizeof(peer)); 02711 port = strchr(peer, ':'); 02712 if (port) 02713 *port++ = '\0'; 02714 dialog->sa.sin_family = AF_INET; 02715 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 02716 p = find_peer(peer, NULL, 1); 02717 02718 if (p) { 02719 int res = create_addr_from_peer(dialog, p); 02720 ASTOBJ_UNREF(p, sip_destroy_peer); 02721 return res; 02722 } 02723 hostn = peer; 02724 portno = port ? atoi(port) : STANDARD_SIP_PORT; 02725 if (srvlookup) { 02726 char service[MAXHOSTNAMELEN]; 02727 int tportno; 02728 int ret; 02729 02730 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 02731 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 02732 if (ret > 0) { 02733 hostn = host; 02734 portno = tportno; 02735 } 02736 } 02737 hp = ast_gethostbyname(hostn, &ahp); 02738 if (!hp) { 02739 ast_log(LOG_WARNING, "No such host: %s\n", peer); 02740 return -1; 02741 } 02742 ast_string_field_set(dialog, tohost, peer); 02743 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 02744 dialog->sa.sin_port = htons(portno); 02745 dialog->recv = dialog->sa; 02746 return 0; 02747 }
Create address structure from peer reference. return -1 on error, 0 on success.
Definition at line 2595 of file chan_sip.c.
References sip_peer::addr, sip_peer::allowtransfer, sip_pvt::allowtransfer, ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_destroy(), ast_udptl_get_error_correction_scheme(), sip_peer::autoframing, sip_pvt::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_pvt::callgroup, t38properties::capability, sip_peer::capability, sip_pvt::capability, sip_peer::context, context, sip_peer::defaddr, do_setnat(), sip_peer::flags, sip_pvt::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_t38_capability, sip_request::headers, sip_pvt::initreq, t38properties::jointcapability, sip_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().
02596 { 02597 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 02598 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 02599 dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr; 02600 dialog->recv = dialog->sa; 02601 } else 02602 return -1; 02603 02604 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 02605 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 02606 dialog->capability = peer->capability; 02607 if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) { 02608 ast_rtp_destroy(dialog->vrtp); 02609 dialog->vrtp = NULL; 02610 } 02611 dialog->prefs = peer->prefs; 02612 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) { 02613 dialog->t38.capability = global_t38_capability; 02614 if (dialog->udptl) { 02615 if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC ) 02616 dialog->t38.capability |= T38FAX_UDP_EC_FEC; 02617 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY ) 02618 dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 02619 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE ) 02620 dialog->t38.capability |= T38FAX_UDP_EC_NONE; 02621 dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 02622 if (option_debug > 1) 02623 ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability); 02624 } 02625 dialog->t38.jointcapability = dialog->t38.capability; 02626 } else if (dialog->udptl) { 02627 ast_udptl_destroy(dialog->udptl); 02628 dialog->udptl = NULL; 02629 } 02630 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE ); 02631 02632 if (dialog->rtp) { 02633 ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 02634 ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 02635 ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); 02636 ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); 02637 ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); 02638 /* Set Frame packetization */ 02639 ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); 02640 dialog->autoframing = peer->autoframing; 02641 } 02642 if (dialog->vrtp) { 02643 ast_rtp_setdtmf(dialog->vrtp, 0); 02644 ast_rtp_setdtmfcompensate(dialog->vrtp, 0); 02645 ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); 02646 ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); 02647 ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); 02648 } 02649 02650 ast_string_field_set(dialog, peername, peer->username); 02651 ast_string_field_set(dialog, authname, peer->username); 02652 ast_string_field_set(dialog, username, peer->username); 02653 ast_string_field_set(dialog, peersecret, peer->secret); 02654 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 02655 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 02656 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 02657 ast_string_field_set(dialog, tohost, peer->tohost); 02658 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 02659 if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 02660 char *tmpcall; 02661 char *c; 02662 tmpcall = ast_strdupa(dialog->callid); 02663 c = strchr(tmpcall, '@'); 02664 if (c) { 02665 *c = '\0'; 02666 ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain); 02667 } 02668 } 02669 if (ast_strlen_zero(dialog->tohost)) 02670 ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr)); 02671 if (!ast_strlen_zero(peer->fromdomain)) 02672 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 02673 if (!ast_strlen_zero(peer->fromuser)) 02674 ast_string_field_set(dialog, fromuser, peer->fromuser); 02675 dialog->maxtime = peer->maxms; 02676 dialog->callgroup = peer->callgroup; 02677 dialog->pickupgroup = peer->pickupgroup; 02678 dialog->allowtransfer = peer->allowtransfer; 02679 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 02680 /* Minimum is settable or default to 100 ms */ 02681 if (peer->maxms && peer->lastms) 02682 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 02683 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 02684 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 02685 dialog->noncodeccapability |= AST_RTP_DTMF; 02686 else 02687 dialog->noncodeccapability &= ~AST_RTP_DTMF; 02688 ast_string_field_set(dialog, context, peer->context); 02689 dialog->rtptimeout = peer->rtptimeout; 02690 if (peer->call_limit) 02691 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 02692 dialog->maxcallbitrate = peer->maxcallbitrate; 02693 02694 return 0; 02695 }
static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 7571 of file chan_sip.c.
References ast_db_del(), ast_test_flag, ast_update_realtime(), sip_peer::flags, global_flags, SIP_PAGE2_IGNOREREGEXPIRE, and SIP_PAGE2_RT_FROMCONTACT.
Referenced by build_peer(), expire_register(), and parse_register_contact().
07572 { 07573 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 07574 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07575 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL); 07576 else 07577 ast_db_del("SIP/Registry", peer->name); 07578 } 07579 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 6456 of file chan_sip.c.
References ast_log(), sip_request::header, LOG_WARNING, sip_request::rlPart1, and sip_request::rlPart2.
Referenced by parse_request().
06457 { 06458 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 06459 06460 if (!*e) 06461 return -1; 06462 req->rlPart1 = e; /* method or protocol */ 06463 e = ast_skip_nonblanks(e); 06464 if (*e) 06465 *e++ = '\0'; 06466 /* Get URI or status code */ 06467 e = ast_skip_blanks(e); 06468 if ( !*e ) 06469 return -1; 06470 ast_trim_blanks(e); 06471 06472 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 06473 if (strlen(e) < 3) /* status code is 3 digits */ 06474 return -1; 06475 req->rlPart2 = e; 06476 } else { /* We have a request */ 06477 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 06478 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 06479 e++; 06480 if (!*e) 06481 return -1; 06482 } 06483 req->rlPart2 = e; /* URI */ 06484 e = ast_skip_nonblanks(e); 06485 if (*e) 06486 *e++ = '\0'; 06487 e = ast_skip_blanks(e); 06488 if (strcasecmp(e, "SIP/2.0") ) { 06489 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 06490 return -1; 06491 } 06492 } 06493 return 1; 06494 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 15031 of file chan_sip.c.
References __sip_destroy(), ast_channel_trylock, ast_channel_unlock, ast_io_add(), ast_io_change(), AST_IO_IN, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_bridged(), ast_rtp_get_peer(), ast_rtp_get_rtpholdtimeout(), ast_rtp_get_rtpkeepalive(), ast_rtp_get_rtptimeout(), ast_rtp_sendcng(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtptimeout(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, ast_verbose(), FALSE, sip_pvt::flags, iflist, io, sip_pvt::lock, LOG_NOTICE, sip_pvt::next, option_verbose, sip_pvt::owner, sip_pvt::packets, sip_do_reload(), SIP_NEEDDESTROY, sipsock, sipsock_read(), t, and VERBOSE_PREFIX_1.
15032 { 15033 int res; 15034 struct sip_pvt *sip; 15035 struct sip_peer *peer = NULL; 15036 time_t t; 15037 int fastrestart = FALSE; 15038 int lastpeernum = -1; 15039 int curpeernum; 15040 int reloading; 15041 15042 /* Add an I/O event to our SIP UDP socket */ 15043 if (sipsock > -1) 15044 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 15045 15046 /* From here on out, we die whenever asked */ 15047 for(;;) { 15048 /* Check for a reload request */ 15049 ast_mutex_lock(&sip_reload_lock); 15050 reloading = sip_reloading; 15051 sip_reloading = FALSE; 15052 ast_mutex_unlock(&sip_reload_lock); 15053 if (reloading) { 15054 if (option_verbose > 0) 15055 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 15056 sip_do_reload(sip_reloadreason); 15057 15058 /* Change the I/O fd of our UDP socket */ 15059 if (sipsock > -1) 15060 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 15061 } 15062 /* Check for interfaces needing to be killed */ 15063 ast_mutex_lock(&iflock); 15064 restartsearch: 15065 t = time(NULL); 15066 /* don't scan the interface list if it hasn't been a reasonable period 15067 of time since the last time we did it (when MWI is being sent, we can 15068 get back to this point every millisecond or less) 15069 */ 15070 for (sip = iflist; !fastrestart && sip; sip = sip->next) { 15071 ast_mutex_lock(&sip->lock); 15072 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 15073 if (sip->rtp && sip->owner && 15074 (sip->owner->_state == AST_STATE_UP) && 15075 !sip->redirip.sin_addr.s_addr) { 15076 if (sip->lastrtptx && 15077 ast_rtp_get_rtpkeepalive(sip->rtp) && 15078 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) { 15079 /* Need to send an empty RTP packet */ 15080 sip->lastrtptx = time(NULL); 15081 ast_rtp_sendcng(sip->rtp, 0); 15082 } 15083 if (sip->lastrtprx && 15084 (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) && 15085 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) { 15086 /* Might be a timeout now -- see if we're on hold */ 15087 struct sockaddr_in sin; 15088 ast_rtp_get_peer(sip->rtp, &sin); 15089 if (sin.sin_addr.s_addr || 15090 (ast_rtp_get_rtpholdtimeout(sip->rtp) && 15091 (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) { 15092 /* Needs a hangup */ 15093 if (ast_rtp_get_rtptimeout(sip->rtp)) { 15094 while (sip->owner && ast_channel_trylock(sip->owner)) { 15095 ast_mutex_unlock(&sip->lock); 15096 usleep(1); 15097 ast_mutex_lock(&sip->lock); 15098 } 15099 if (sip->owner) { 15100 if (!(ast_rtp_get_bridged(sip->rtp))) { 15101 ast_log(LOG_NOTICE, 15102 "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 15103 sip->owner->name, 15104 (long) (t - sip->lastrtprx)); 15105 /* Issue a softhangup */ 15106 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 15107 } else 15108 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)); 15109 ast_channel_unlock(sip->owner); 15110 /* forget the timeouts for this call, since a hangup 15111 has already been requested and we don't want to 15112 repeatedly request hangups 15113 */ 15114 ast_rtp_set_rtptimeout(sip->rtp, 0); 15115 ast_rtp_set_rtpholdtimeout(sip->rtp, 0); 15116 if (sip->vrtp) { 15117 ast_rtp_set_rtptimeout(sip->vrtp, 0); 15118 ast_rtp_set_rtpholdtimeout(sip->vrtp, 0); 15119 } 15120 } 15121 } 15122 } 15123 } 15124 } 15125 /* If we have sessions that needs to be destroyed, do it now */ 15126 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && 15127 !sip->owner) { 15128 ast_mutex_unlock(&sip->lock); 15129 __sip_destroy(sip, 1); 15130 goto restartsearch; 15131 } 15132 ast_mutex_unlock(&sip->lock); 15133 } 15134 ast_mutex_unlock(&iflock); 15135 15136 pthread_testcancel(); 15137 /* Wait for sched or io */ 15138 res = ast_sched_wait(sched); 15139 if ((res < 0) || (res > 1000)) 15140 res = 1000; 15141 /* If we might need to send more mailboxes, don't wait long at all.*/ 15142 if (fastrestart) 15143 res = 1; 15144 res = ast_io_wait(io, res); 15145 if (option_debug && res > 20) 15146 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 15147 ast_mutex_lock(&monlock); 15148 if (res >= 0) { 15149 res = ast_sched_runq(sched); 15150 if (option_debug && res >= 20) 15151 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 15152 } 15153 15154 /* Send MWI notifications to peers - static and cached realtime peers */ 15155 t = time(NULL); 15156 fastrestart = FALSE; 15157 curpeernum = 0; 15158 peer = NULL; 15159 /* Find next peer that needs mwi */ 15160 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 15161 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 15162 fastrestart = TRUE; 15163 lastpeernum = curpeernum; 15164 peer = ASTOBJ_REF(iterator); 15165 }; 15166 curpeernum++; 15167 } while (0) 15168 ); 15169 /* Send MWI to the peer */ 15170 if (peer) { 15171 ASTOBJ_WRLOCK(peer); 15172 sip_send_mwi_to_peer(peer); 15173 ASTOBJ_UNLOCK(peer); 15174 ASTOBJ_UNREF(peer,sip_destroy_peer); 15175 } else { 15176 /* Reset where we come from */ 15177 lastpeernum = -1; 15178 } 15179 ast_mutex_unlock(&monlock); 15180 } 15181 /* Never reached */ 15182 return NULL; 15183 15184 }
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 11093 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().
11094 { 11095 char digest[1024]; 11096 11097 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 11098 return -2; 11099 11100 p->authtries++; 11101 if (option_debug > 1) 11102 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 11103 memset(digest, 0, sizeof(digest)); 11104 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 11105 /* No way to authenticate */ 11106 return -1; 11107 } 11108 /* Now we have a reply digest */ 11109 p->options->auth = digest; 11110 p->options->authheader = respheader; 11111 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 11112 }
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 11072 of file chan_sip.c.
References append_history, ast_test_flag, ast_verbose(), sip_pvt::authtries, sip_pvt::flags, reply_digest(), sip_debug_test_pvt(), SIP_NO_HISTORY, SIP_REGISTER, and transmit_register().
Referenced by handle_response_register().
11073 { 11074 char digest[1024]; 11075 p->authtries++; 11076 memset(digest,0,sizeof(digest)); 11077 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 11078 /* There's nothing to use for authentication */ 11079 /* No digest challenge in request */ 11080 if (sip_debug_test_pvt(p) && p->registry) 11081 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 11082 /* No old challenge */ 11083 return -1; 11084 } 11085 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 11086 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 11087 if (sip_debug_test_pvt(p) && p->registry) 11088 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 11089 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 11090 }
static void do_setnat | ( | struct sip_pvt * | p, | |
int | natflags | |||
) | [static] |
Set nat mode on the various data sockets.
Definition at line 2571 of file chan_sip.c.
References ast_log(), ast_rtp_setnat(), ast_udptl_setnat(), LOG_DEBUG, option_debug, sip_pvt::rtp, sip_pvt::udptl, and sip_pvt::vrtp.
Referenced by check_user_full(), create_addr_from_peer(), sip_alloc(), and transmit_response_using_temp().
02572 { 02573 const char *mode = natflags ? "On" : "Off"; 02574 02575 if (p->rtp) { 02576 if (option_debug) 02577 ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode); 02578 ast_rtp_setnat(p->rtp, natflags); 02579 } 02580 if (p->vrtp) { 02581 if (option_debug) 02582 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode); 02583 ast_rtp_setnat(p->vrtp, natflags); 02584 } 02585 if (p->udptl) { 02586 if (option_debug) 02587 ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode); 02588 ast_udptl_setnat(p->udptl, natflags); 02589 } 02590 }
static int does_peer_need_mwi | ( | struct sip_peer * | peer | ) | [static] |
Check whether peer needs a new MWI notification check.
Definition at line 15010 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.
15011 { 15012 time_t t = time(NULL); 15013 15014 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 15015 !peer->mwipvt) { /* We don't have a subscription */ 15016 peer->lastmsgcheck = t; /* Reset timer */ 15017 return FALSE; 15018 } 15019 15020 if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime) 15021 return TRUE; 15022 15023 return FALSE; 15024 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 9933 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
09934 { 09935 switch (mode) { 09936 case SIP_DOMAIN_AUTO: 09937 return "[Automatic]"; 09938 case SIP_DOMAIN_CONFIG: 09939 return "[Configured]"; 09940 } 09941 09942 return ""; 09943 }
static const char * dtmfmode2str | ( | int | mode | ) | const [static] |
Convert DTMF mode to printable string.
Definition at line 9713 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().
09714 { 09715 switch (mode) { 09716 case SIP_DTMF_RFC2833: 09717 return "rfc2833"; 09718 case SIP_DTMF_INFO: 09719 return "info"; 09720 case SIP_DTMF_INBAND: 09721 return "inband"; 09722 case SIP_DTMF_AUTO: 09723 return "auto"; 09724 } 09725 return "<error>"; 09726 }
static int expire_register | ( | void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 7582 of file chan_sip.c.
References sip_peer::addr, ast_device_state_changed(), ast_test_flag, ASTOBJ_CONTAINER_UNLINK, ASTOBJ_UNREF, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, FALSE, sip_peer::flags, manager_event(), peerl, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RTAUTOCLEAR, and SIP_PAGE2_SELFDESTRUCT.
Referenced by parse_register_contact(), and reg_source_db().
07583 { 07584 struct sip_peer *peer = data; 07585 07586 if (!peer) /* Hmmm. We have no peer. Weird. */ 07587 return 0; 07588 07589 memset(&peer->addr, 0, sizeof(peer->addr)); 07590 07591 destroy_association(peer); /* remove registration data from storage */ 07592 07593 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 07594 register_peer_exten(peer, FALSE); /* Remove regexten */ 07595 peer->expire = -1; 07596 ast_device_state_changed("SIP/%s", peer->name); 07597 07598 /* Do we need to release this peer from memory? 07599 Only for realtime peers and autocreated peers 07600 */ 07601 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) || 07602 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 07603 peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); /* Remove from peer list */ 07604 ASTOBJ_UNREF(peer, sip_destroy_peer); /* Remove from memory */ 07605 } 07606 07607 return 0; 07608 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 6546 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().
06547 { 06548 char stripped[BUFSIZ]; 06549 char *c; 06550 06551 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 06552 c = get_in_brackets(stripped); 06553 c = strsep(&c, ";"); /* trim ; and beyond */ 06554 if (!ast_strlen_zero(c)) 06555 ast_string_field_set(p, uri, c); 06556 }
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 3970 of file chan_sip.c.
References aliases.
03971 { 03972 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 03973 static const struct cfalias { 03974 char * const fullname; 03975 char * const shortname; 03976 } aliases[] = { 03977 { "Content-Type", "c" }, 03978 { "Content-Encoding", "e" }, 03979 { "From", "f" }, 03980 { "Call-ID", "i" }, 03981 { "Contact", "m" }, 03982 { "Content-Length", "l" }, 03983 { "Subject", "s" }, 03984 { "To", "t" }, 03985 { "Supported", "k" }, 03986 { "Refer-To", "r" }, 03987 { "Referred-By", "b" }, 03988 { "Allow-Events", "u" }, 03989 { "Event", "o" }, 03990 { "Via", "v" }, 03991 { "Accept-Contact", "a" }, 03992 { "Reject-Contact", "j" }, 03993 { "Request-Disposition", "d" }, 03994 { "Session-Expires", "x" }, 03995 { "Identity", "y" }, 03996 { "Identity-Info", "n" }, 03997 }; 03998 int x; 03999 04000 for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 04001 if (!strcasecmp(aliases[x].fullname, name)) 04002 return aliases[x].shortname; 04003 04004 return _default; 04005 }
static struct sip_pvt * find_call | ( | struct sip_request * | req, | |
struct sockaddr_in * | sin, | |||
const int | intended_method | |||
) | [static] |
Connect incoming SIP message to current dialog or create new dialog structure Called by handle_request, sipsock_read.
Definition at line 4329 of file chan_sip.c.
References ast_log(), ast_mutex_lock(), ast_set_flag, ast_strlen_zero(), FALSE, get_header(), gettag(), iflist, LOG_DEBUG, sip_request::method, sip_pvt::next, option_debug, SIP_PKT_WITH_TOTAG, SIP_REGISTER, SIP_RESPONSE, and sip_pvt::tag.
Referenced by sipsock_read().
04330 { 04331 struct sip_pvt *p = NULL; 04332 char *tag = ""; /* note, tag is never NULL */ 04333 char totag[128]; 04334 char fromtag[128]; 04335 const char *callid = get_header(req, "Call-ID"); 04336 const char *from = get_header(req, "From"); 04337 const char *to = get_header(req, "To"); 04338 const char *cseq = get_header(req, "Cseq"); 04339 04340 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 04341 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 04342 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 04343 ast_strlen_zero(from) || ast_strlen_zero(cseq)) 04344 return NULL; /* Invalid packet */ 04345 04346 if (pedanticsipchecking) { 04347 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 04348 we need more to identify a branch - so we have to check branch, from 04349 and to tags to identify a call leg. 04350 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 04351 in sip.conf 04352 */ 04353 if (gettag(req, "To", totag, sizeof(totag))) 04354 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 04355 gettag(req, "From", fromtag, sizeof(fromtag)); 04356 04357 tag = (req->method == SIP_RESPONSE) ? totag : fromtag; 04358 04359 if (option_debug > 4 ) 04360 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); 04361 } 04362 04363 ast_mutex_lock(&iflock); 04364 for (p = iflist; p; p = p->next) { 04365 /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 04366 int found = FALSE; 04367 if (ast_strlen_zero(p->callid)) 04368 continue; 04369 if (req->method == SIP_REGISTER) 04370 found = (!strcmp(p->callid, callid)); 04371 else 04372 found = (!strcmp(p->callid, callid) && 04373 (!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ; 04374 04375 if (option_debug > 4) 04376 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); 04377 04378 /* If we get a new request within an existing to-tag - check the to tag as well */ 04379 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 04380 if (p->tag[0] == '\0' && totag[0]) { 04381 /* We have no to tag, but they have. Wrong dialog */ 04382 found = FALSE; 04383 } else if (totag[0]) { /* Both have tags, compare them */ 04384 if (strcmp(totag, p->tag)) { 04385 found = FALSE; /* This is not our packet */ 04386 } 04387 } 04388 if (!found && option_debug > 4) 04389 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); 04390 } 04391 04392 04393 if (found) { 04394 /* Found the call */ 04395 ast_mutex_unlock(&iflock); 04396 ast_mutex_lock(&p->lock); 04397 return p; 04398 } 04399 } 04400 ast_mutex_unlock(&iflock); 04401 04402 /* See if the method is capable of creating a dialog */ 04403 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 04404 if (intended_method == SIP_REFER) { 04405 /* We do support REFER, but not outside of a dialog yet */ 04406 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 04407 } else if (intended_method == SIP_NOTIFY) { 04408 /* We do not support out-of-dialog NOTIFY either, 04409 like voicemail notification, so cancel that early */ 04410 transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); 04411 } else { 04412 /* Ok, time to create a new SIP dialog object, a pvt */ 04413 if ((p = sip_alloc(callid, sin, 1, intended_method))) { 04414 /* Ok, we've created a dialog, let's go and process it */ 04415 ast_mutex_lock(&p->lock); 04416 } else { 04417 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 04418 getting a dialog from sip_alloc. 04419 04420 Without a dialog we can't retransmit and handle ACKs and all that, but at least 04421 send an error message. 04422 04423 Sorry, we apologize for the inconvienience 04424 */ 04425 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 04426 if (option_debug > 3) 04427 ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 04428 } 04429 } 04430 return p; 04431 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 04432 /* A method we do not support, let's take it on the volley */ 04433 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 04434 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 04435 /* This is a request outside of a dialog that we don't know about 04436 ...never reply to an ACK! 04437 */ 04438 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 04439 } 04440 /* We do not respond to responses for dialogs that we don't know about, we just drop 04441 the session quickly */ 04442 04443 return p; 04444 }
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 2212 of file chan_sip.c.
References s.
Referenced by get_in_brackets().
02213 { 02214 char last_char = '\0'; 02215 const char *s; 02216 for (s = start; *s && s != lim; last_char = *s++) { 02217 if (*s == '"' && last_char != '\\') 02218 break; 02219 } 02220 return s; 02221 }
static struct sip_peer * find_peer | ( | const char * | peer, | |
struct sockaddr_in * | sin, | |||
int | realtime | |||
) | [static] |
Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name.
Definition at line 2483 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().
02484 { 02485 struct sip_peer *p = NULL; 02486 02487 if (peer) 02488 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 02489 else 02490 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); 02491 02492 if (!p && realtime) 02493 p = realtime_peer(peer, sin); 02494 02495 return p; 02496 }
static struct sip_auth * find_realm_authentication | ( | struct sip_auth * | authlist, | |
const char * | realm | |||
) | [static] |
Find authentication for a specific realm.
Definition at line 15761 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
15762 { 15763 struct sip_auth *a; 15764 15765 for (a = authlist; a; a = a->next) { 15766 if (!strcasecmp(a->realm, realm)) 15767 break; 15768 } 15769 15770 return a; 15771 }
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 4650 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().
04651 { 04652 const char *content_type; 04653 const char *search; 04654 char *boundary; 04655 unsigned int x; 04656 int boundaryisquoted = FALSE; 04657 04658 content_type = get_header(req, "Content-Type"); 04659 04660 /* if the body contains only SDP, this is easy */ 04661 if (!strcasecmp(content_type, "application/sdp")) { 04662 req->sdp_start = 0; 04663 req->sdp_end = req->lines; 04664 return 1; 04665 } 04666 04667 /* if it's not multipart/mixed, there cannot be an SDP */ 04668 if (strncasecmp(content_type, "multipart/mixed", 15)) 04669 return 0; 04670 04671 /* if there is no boundary marker, it's invalid */ 04672 if (!(search = strcasestr(content_type, ";boundary="))) 04673 return 0; 04674 04675 search += 10; 04676 if (ast_strlen_zero(search)) 04677 return 0; 04678 04679 /* If the boundary is quoted with ", remove quote */ 04680 if (*search == '\"') { 04681 search++; 04682 boundaryisquoted = TRUE; 04683 } 04684 04685 /* make a duplicate of the string, with two extra characters 04686 at the beginning */ 04687 boundary = ast_strdupa(search - 2); 04688 boundary[0] = boundary[1] = '-'; 04689 04690 /* Remove final quote */ 04691 if (boundaryisquoted) 04692 boundary[strlen(boundary) - 1] = '\0'; 04693 04694 /* search for the boundary marker, but stop when there are not enough 04695 lines left for it, the Content-Type header and at least one line of 04696 body */ 04697 for (x = 0; x < (req->lines - 2); x++) { 04698 if (!strncasecmp(req->line[x], boundary, strlen(boundary)) && 04699 !strcasecmp(req->line[x + 1], "Content-Type: application/sdp")) { 04700 x += 2; 04701 req->sdp_start = x; 04702 04703 /* search for the end of the body part */ 04704 for ( ; x < req->lines; x++) { 04705 if (!strncasecmp(req->line[x], boundary, strlen(boundary))) 04706 break; 04707 } 04708 req->sdp_end = x; 04709 return 1; 04710 } 04711 } 04712 04713 return 0; 04714 }
static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 1656 of file chan_sip.c.
References ast_strlen_zero(), method_match(), and sip_methods.
Referenced by __sip_pretend_ack(), handle_response(), and sipsock_read().
01657 { 01658 int i, res = 0; 01659 01660 if (ast_strlen_zero(msg)) 01661 return 0; 01662 for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) { 01663 if (method_match(i, msg)) 01664 res = sip_methods[i].id; 01665 } 01666 return res; 01667 }
static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static] |
Find subscription type in array.
Definition at line 10427 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
10428 { 10429 int i; 10430 10431 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10432 if (subscription_types[i].type == subtype) { 10433 return &subscription_types[i]; 10434 } 10435 } 10436 return &subscription_types[0]; 10437 }
static struct sip_user * find_user | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf).
Definition at line 2562 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.
02563 { 02564 struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name); 02565 if (!u && realtime) 02566 u = realtime_user(name); 02567 return u; 02568 }
static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 7915 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
07916 { 07917 struct sip_route *next; 07918 07919 while (route) { 07920 next = route->next; 07921 free(route); 07922 route = next; 07923 } 07924 }
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 11419 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING.
11420 { 11421 if (ast_strlen_zero(data)) { 11422 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 11423 return -1; 11424 } 11425 if (check_sip_domain(data, NULL, 0)) 11426 ast_copy_string(buf, data, len); 11427 else 11428 buf[0] = '\0'; 11429 return 0; 11430 }
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 11355 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.
11356 { 11357 struct sip_pvt *p; 11358 const char *content = NULL; 11359 AST_DECLARE_APP_ARGS(args, 11360 AST_APP_ARG(header); 11361 AST_APP_ARG(number); 11362 ); 11363 int i, number, start = 0; 11364 11365 if (ast_strlen_zero(data)) { 11366 ast_log(LOG_WARNING, "This function requires a header name.\n"); 11367 return -1; 11368 } 11369 11370 ast_channel_lock(chan); 11371 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11372 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11373 ast_channel_unlock(chan); 11374 return -1; 11375 } 11376 11377 AST_STANDARD_APP_ARGS(args, data); 11378 if (!args.number) { 11379 number = 1; 11380 } else { 11381 sscanf(args.number, "%d", &number); 11382 if (number < 1) 11383 number = 1; 11384 } 11385 11386 p = chan->tech_pvt; 11387 11388 /* If there is no private structure, this channel is no longer alive */ 11389 if (!p) { 11390 ast_channel_unlock(chan); 11391 return -1; 11392 } 11393 11394 for (i = 0; i < number; i++) 11395 content = __get_header(&p->initreq, args.header, &start); 11396 11397 if (ast_strlen_zero(content)) { 11398 ast_channel_unlock(chan); 11399 return -1; 11400 } 11401 11402 ast_copy_string(buf, content, len); 11403 ast_channel_unlock(chan); 11404 11405 return 0; 11406 }
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 11534 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.
11535 { 11536 struct sip_pvt *p; 11537 11538 *buf = 0; 11539 11540 if (!data) { 11541 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 11542 return -1; 11543 } 11544 11545 ast_channel_lock(chan); 11546 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11547 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11548 ast_channel_unlock(chan); 11549 return -1; 11550 } 11551 11552 p = chan->tech_pvt; 11553 11554 /* If there is no private structure, this channel is no longer alive */ 11555 if (!p) { 11556 ast_channel_unlock(chan); 11557 return -1; 11558 } 11559 11560 if (!strcasecmp(data, "peerip")) { 11561 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 11562 } else if (!strcasecmp(data, "recvip")) { 11563 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 11564 } else if (!strcasecmp(data, "from")) { 11565 ast_copy_string(buf, p->from, len); 11566 } else if (!strcasecmp(data, "uri")) { 11567 ast_copy_string(buf, p->uri, len); 11568 } else if (!strcasecmp(data, "useragent")) { 11569 ast_copy_string(buf, p->useragent, len); 11570 } else if (!strcasecmp(data, "peername")) { 11571 ast_copy_string(buf, p->peername, len); 11572 } else if (!strcasecmp(data, "t38passthrough")) { 11573 if (p->t38.state == T38_DISABLED) 11574 ast_copy_string(buf, "0", sizeof("0")); 11575 else /* T38 is offered or enabled in this call */ 11576 ast_copy_string(buf, "1", sizeof("1")); 11577 } else { 11578 ast_channel_unlock(chan); 11579 return -1; 11580 } 11581 ast_channel_unlock(chan); 11582 11583 return 0; 11584 }
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 11444 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.
11445 { 11446 struct sip_peer *peer; 11447 char *colname; 11448 11449 if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */ 11450 *colname++ = '\0'; 11451 else if ((colname = strchr(data, '|'))) 11452 *colname++ = '\0'; 11453 else 11454 colname = "ip"; 11455 11456 if (!(peer = find_peer(data, NULL, 1))) 11457 return -1; 11458 11459 if (!strcasecmp(colname, "ip")) { 11460 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 11461 } else if (!strcasecmp(colname, "status")) { 11462 peer_status(peer, buf, len); 11463 } else if (!strcasecmp(colname, "language")) { 11464 ast_copy_string(buf, peer->language, len); 11465 } else if (!strcasecmp(colname, "regexten")) { 11466 ast_copy_string(buf, peer->regexten, len); 11467 } else if (!strcasecmp(colname, "limit")) { 11468 snprintf(buf, len, "%d", peer->call_limit); 11469 } else if (!strcasecmp(colname, "curcalls")) { 11470 snprintf(buf, len, "%d", peer->inUse); 11471 } else if (!strcasecmp(colname, "accountcode")) { 11472 ast_copy_string(buf, peer->accountcode, len); 11473 } else if (!strcasecmp(colname, "useragent")) { 11474 ast_copy_string(buf, peer->useragent, len); 11475 } else if (!strcasecmp(colname, "mailbox")) { 11476 ast_copy_string(buf, peer->mailbox, len); 11477 } else if (!strcasecmp(colname, "context")) { 11478 ast_copy_string(buf, peer->context, len); 11479 } else if (!strcasecmp(colname, "expire")) { 11480 snprintf(buf, len, "%d", peer->expire); 11481 } else if (!strcasecmp(colname, "dynamic")) { 11482 ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 11483 } else if (!strcasecmp(colname, "callerid_name")) { 11484 ast_copy_string(buf, peer->cid_name, len); 11485 } else if (!strcasecmp(colname, "callerid_num")) { 11486 ast_copy_string(buf, peer->cid_num, len); 11487 } else if (!strcasecmp(colname, "codecs")) { 11488 ast_getformatname_multiple(buf, len -1, peer->capability); 11489 } else if (!strncasecmp(colname, "codec[", 6)) { 11490 char *codecnum; 11491 int index = 0, codec = 0; 11492 11493 codecnum = colname + 6; /* move past the '[' */ 11494 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 11495 index = atoi(codecnum); 11496 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 11497 ast_copy_string(buf, ast_getformatname(codec), len); 11498 } 11499 } 11500 11501 ASTOBJ_UNREF(peer, sip_destroy_peer); 11502 11503 return 0; 11504 }
static char * generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 4163 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), and build_callid_registry().
04164 { 04165 long val[4]; 04166 int x; 04167 04168 for (x=0; x<4; x++) 04169 val[x] = ast_random(); 04170 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 04171 04172 return buf; 04173 }
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 8801 of file chan_sip.c.
References ast_canmatch_extension(), ast_exists_extension(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, 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().
08802 { 08803 char tmp[256] = "", *c, *a; 08804 struct sip_request *req = oreq ? oreq : &p->initreq; 08805 struct sip_refer *referdata = p->refer; 08806 const char *transfer_context = NULL; 08807 08808 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 08809 c = get_in_brackets(tmp); 08810 08811 if (pedanticsipchecking) 08812 ast_uri_decode(c); 08813 08814 if (strncmp(c, "sip:", 4)) { 08815 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 08816 return -1; 08817 } 08818 c += 4; 08819 if ((a = strchr(c, ';'))) /* Remove arguments */ 08820 *a = '\0'; 08821 08822 if ((a = strchr(c, '@'))) { /* Separate Domain */ 08823 *a++ = '\0'; 08824 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 08825 } 08826 08827 if (sip_debug_test_pvt(p)) 08828 ast_verbose("Looking for %s in %s\n", c, p->context); 08829 08830 if (p->owner) /* Mimic behaviour in res_features.c */ 08831 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 08832 08833 /* By default, use the context in the channel sending the REFER */ 08834 if (ast_strlen_zero(transfer_context)) { 08835 transfer_context = S_OR(p->owner->macrocontext, 08836 S_OR(p->context, default_context)); 08837 } 08838 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 08839 /* This is a blind transfer */ 08840 if (option_debug) 08841 ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 08842 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 08843 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 08844 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 08845 referdata->refer_call = NULL; 08846 /* Set new context */ 08847 ast_string_field_set(p, context, transfer_context); 08848 return 0; 08849 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 08850 return 1; 08851 } 08852 08853 return -1; 08854 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
Get a specific line from the message body.
Definition at line 3954 of file chan_sip.c.
References get_body_by_line(), len, sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
03955 { 03956 int x; 03957 int len = strlen(name); 03958 char *r; 03959 03960 for (x = 0; x < req->lines; x++) { 03961 r = get_body_by_line(req->line[x], name, len); 03962 if (r[0] != '\0') 03963 return r; 03964 } 03965 03966 return ""; 03967 }
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 3920 of file chan_sip.c.
Referenced by get_body(), and get_sdp_iterate().
03921 { 03922 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') 03923 return ast_skip_blanks(line + nameLen + 1); 03924 03925 return ""; 03926 }
static char * get_calleridname | ( | const char * | input, | |
char * | output, | |||
size_t | outputsize | |||
) | [static] |
Get caller id name from SIP headers.
Definition at line 8908 of file chan_sip.c.
Referenced by check_user_full().
08909 { 08910 const char *end = strchr(input,'<'); /* first_bracket */ 08911 const char *tmp = strchr(input,'"'); /* first quote */ 08912 int bytes = 0; 08913 int maxbytes = outputsize - 1; 08914 08915 if (!end || end == input) /* we require a part in brackets */ 08916 return NULL; 08917 08918 end--; /* move just before "<" */ 08919 08920 if (tmp && tmp <= end) { 08921 /* The quote (tmp) precedes the bracket (end+1). 08922 * Find the matching quote and return the content. 08923 */ 08924 end = strchr(tmp+1, '"'); 08925 if (!end) 08926 return NULL; 08927 bytes = (int) (end - tmp); 08928 /* protect the output buffer */ 08929 if (bytes > maxbytes) 08930 bytes = maxbytes; 08931 ast_copy_string(output, tmp + 1, bytes); 08932 } else { 08933 /* No quoted string, or it is inside brackets. */ 08934 /* clear the empty characters in the begining*/ 08935 input = ast_skip_blanks(input); 08936 /* clear the empty characters in the end */ 08937 while(*end && *end < 33 && end > input) 08938 end--; 08939 if (end >= input) { 08940 bytes = (int) (end - input) + 2; 08941 /* protect the output buffer */ 08942 if (bytes > maxbytes) 08943 bytes = maxbytes; 08944 ast_copy_string(output, input, bytes); 08945 } else 08946 return NULL; 08947 } 08948 return output; 08949 }
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 8475 of file chan_sip.c.
References ast_canmatch_extension(), ast_exists_extension(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), check_sip_domain(), context, exten, get_header(), get_in_brackets(), global_flags, sip_pvt::initreq, LOG_DEBUG, 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().
08476 { 08477 char tmp[256] = "", *uri, *a; 08478 char tmpf[256] = "", *from; 08479 struct sip_request *req; 08480 char *colon; 08481 08482 req = oreq; 08483 if (!req) 08484 req = &p->initreq; 08485 08486 /* Find the request URI */ 08487 if (req->rlPart2) 08488 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 08489 08490 if (pedanticsipchecking) 08491 ast_uri_decode(tmp); 08492 08493 uri = get_in_brackets(tmp); 08494 08495 if (strncmp(uri, "sip:", 4)) { 08496 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 08497 return -1; 08498 } 08499 uri += 4; 08500 08501 /* Now find the From: caller ID and name */ 08502 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 08503 if (!ast_strlen_zero(tmpf)) { 08504 if (pedanticsipchecking) 08505 ast_uri_decode(tmpf); 08506 from = get_in_brackets(tmpf); 08507 } else { 08508 from = NULL; 08509 } 08510 08511 if (!ast_strlen_zero(from)) { 08512 if (strncmp(from, "sip:", 4)) { 08513 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 08514 return -1; 08515 } 08516 from += 4; 08517 if ((a = strchr(from, '@'))) 08518 *a++ = '\0'; 08519 else 08520 a = from; /* just a domain */ 08521 from = strsep(&from, ";"); /* Remove userinfo options */ 08522 a = strsep(&a, ";"); /* Remove URI options */ 08523 ast_string_field_set(p, fromdomain, a); 08524 } 08525 08526 /* Skip any options and find the domain */ 08527 08528 /* Get the target domain */ 08529 if ((a = strchr(uri, '@'))) { 08530 *a++ = '\0'; 08531 } else { /* No username part */ 08532 a = uri; 08533 uri = "s"; /* Set extension to "s" */ 08534 } 08535 colon = strchr(a, ':'); /* Remove :port */ 08536 if (colon) 08537 *colon = '\0'; 08538 08539 uri = strsep(&uri, ";"); /* Remove userinfo options */ 08540 a = strsep(&a, ";"); /* Remove URI options */ 08541 08542 ast_string_field_set(p, domain, a); 08543 08544 if (!AST_LIST_EMPTY(&domain_list)) { 08545 char domain_context[AST_MAX_EXTENSION]; 08546 08547 domain_context[0] = '\0'; 08548 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 08549 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 08550 if (option_debug) 08551 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 08552 return -2; 08553 } 08554 } 08555 /* If we have a context defined, overwrite the original context */ 08556 if (!ast_strlen_zero(domain_context)) 08557 ast_string_field_set(p, context, domain_context); 08558 } 08559 08560 if (sip_debug_test_pvt(p)) 08561 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 08562 08563 /* Check the dialplan for the username part of the request URI, 08564 the domain will be stored in the SIPDOMAIN variable 08565 Return 0 if we have a matching extension */ 08566 if (ast_exists_extension(NULL, p->context, uri, 1, from) || 08567 !strcmp(uri, ast_pickup_ext())) { 08568 if (!oreq) 08569 ast_string_field_set(p, exten, uri); 08570 return 0; 08571 } 08572 08573 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 08574 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 08575 ast_canmatch_extension(NULL, p->context, uri, 1, from)) || 08576 !strncmp(uri, ast_pickup_ext(), strlen(uri))) { 08577 return 1; 08578 } 08579 08580 return -1; 08581 }
static const char * get_header | ( | const struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get header from SIP request.
Definition at line 4043 of file chan_sip.c.
References __get_header().
04044 { 04045 int start = 0; 04046 return __get_header(req, name, &start); 04047 }
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 2234 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().
02235 { 02236 const char *parse = tmp; 02237 char *first_bracket; 02238 02239 /* 02240 * Skip any quoted text until we find the part in brackets. 02241 * On any error give up and return the full string. 02242 */ 02243 while ( (first_bracket = strchr(parse, '<')) ) { 02244 char *first_quote = strchr(parse, '"'); 02245 02246 if (!first_quote || first_quote > first_bracket) 02247 break; /* no need to look at quoted part */ 02248 /* the bracket is within quotes, so ignore it */ 02249 parse = find_closing_quote(first_quote + 1, NULL); 02250 if (!*parse) { /* not found, return full string ? */ 02251 /* XXX or be robust and return in-bracket part ? */ 02252 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 02253 break; 02254 } 02255 parse++; 02256 } 02257 if (first_bracket) { 02258 char *second_bracket = strchr(first_bracket + 1, '>'); 02259 if (second_bracket) { 02260 *second_bracket = '\0'; 02261 tmp = first_bracket + 1; 02262 } else { 02263 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 02264 } 02265 } 02266 return tmp; 02267 }
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 9308 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_notify(), and receive_message().
09309 { 09310 int x; 09311 int y; 09312 09313 buf[0] = '\0'; 09314 y = len - strlen(buf) - 5; 09315 if (y < 0) 09316 y = 0; 09317 for (x=0;x<req->lines;x++) { 09318 strncat(buf, req->line[x], y); /* safe */ 09319 y -= strlen(req->line[x]) + 1; 09320 if (y < 0) 09321 y = 0; 09322 if (y != 0) 09323 strcat(buf, "\n"); /* safe */ 09324 } 09325 return 0; 09326 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Get referring dnis.
Definition at line 8446 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().
08447 { 08448 char tmp[256], *c, *a; 08449 struct sip_request *req; 08450 08451 req = oreq; 08452 if (!req) 08453 req = &p->initreq; 08454 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 08455 if (ast_strlen_zero(tmp)) 08456 return 0; 08457 c = get_in_brackets(tmp); 08458 if (strncmp(c, "sip:", 4)) { 08459 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 08460 return -1; 08461 } 08462 c += 4; 08463 a = c; 08464 strsep(&a, "@;"); /* trim anything after @ or ; */ 08465 if (sip_debug_test_pvt(p)) 08466 ast_verbose("RDNIS is %s\n", c); 08467 ast_string_field_set(p, rdnis, c); 08468 08469 return 0; 08470 }
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 8640 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().
08641 { 08642 08643 const char *p_referred_by = NULL; 08644 char *h_refer_to = NULL; 08645 char *h_referred_by = NULL; 08646 char *refer_to; 08647 const char *p_refer_to; 08648 char *referred_by_uri = NULL; 08649 char *ptr; 08650 struct sip_request *req = NULL; 08651 const char *transfer_context = NULL; 08652 struct sip_refer *referdata; 08653 08654 08655 req = outgoing_req; 08656 referdata = transferer->refer; 08657 08658 if (!req) 08659 req = &transferer->initreq; 08660 08661 p_refer_to = get_header(req, "Refer-To"); 08662 if (ast_strlen_zero(p_refer_to)) { 08663 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 08664 return -2; /* Syntax error */ 08665 } 08666 h_refer_to = ast_strdupa(p_refer_to); 08667 refer_to = get_in_brackets(h_refer_to); 08668 if (pedanticsipchecking) 08669 ast_uri_decode(refer_to); 08670 08671 if (strncasecmp(refer_to, "sip:", 4)) { 08672 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 08673 return -3; 08674 } 08675 refer_to += 4; /* Skip sip: */ 08676 08677 /* Get referred by header if it exists */ 08678 p_referred_by = get_header(req, "Referred-By"); 08679 if (!ast_strlen_zero(p_referred_by)) { 08680 char *lessthan; 08681 h_referred_by = ast_strdupa(p_referred_by); 08682 if (pedanticsipchecking) 08683 ast_uri_decode(h_referred_by); 08684 08685 /* Store referrer's caller ID name */ 08686 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 08687 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 08688 *(lessthan - 1) = '\0'; /* Space */ 08689 } 08690 08691 referred_by_uri = get_in_brackets(h_referred_by); 08692 if(strncasecmp(referred_by_uri, "sip:", 4)) { 08693 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 08694 referred_by_uri = (char *) NULL; 08695 } else { 08696 referred_by_uri += 4; /* Skip sip: */ 08697 } 08698 } 08699 08700 /* Check for arguments in the refer_to header */ 08701 if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */ 08702 *ptr++ = '\0'; 08703 if (!strncasecmp(ptr, "REPLACES=", 9)) { 08704 char *to = NULL, *from = NULL; 08705 08706 /* This is an attended transfer */ 08707 referdata->attendedtransfer = 1; 08708 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 08709 ast_uri_decode(referdata->replaces_callid); 08710 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 08711 *ptr++ = '\0'; 08712 } 08713 08714 if (ptr) { 08715 /* Find the different tags before we destroy the string */ 08716 to = strcasestr(ptr, "to-tag="); 08717 from = strcasestr(ptr, "from-tag="); 08718 } 08719 08720 /* Grab the to header */ 08721 if (to) { 08722 ptr = to + 7; 08723 if ((to = strchr(ptr, '&'))) 08724 *to = '\0'; 08725 if ((to = strchr(ptr, ';'))) 08726 *to = '\0'; 08727 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 08728 } 08729 08730 if (from) { 08731 ptr = from + 9; 08732 if ((to = strchr(ptr, '&'))) 08733 *to = '\0'; 08734 if ((to = strchr(ptr, ';'))) 08735 *to = '\0'; 08736 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 08737 } 08738 08739 if (option_debug > 1) { 08740 if (!pedanticsipchecking) 08741 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 08742 else 08743 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>" ); 08744 } 08745 } 08746 } 08747 08748 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 08749 char *urioption; 08750 08751 *ptr++ = '\0'; 08752 if ((urioption = strchr(ptr, ';'))) 08753 *urioption++ = '\0'; 08754 /* Save the domain for the dial plan */ 08755 ast_copy_string(referdata->refer_to_domain, ptr, sizeof(referdata->refer_to_domain)); 08756 if (urioption) 08757 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 08758 } 08759 08760 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 08761 *ptr = '\0'; 08762 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 08763 08764 if (referred_by_uri) { 08765 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 08766 *ptr = '\0'; 08767 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 08768 } else { 08769 referdata->referred_by[0] = '\0'; 08770 } 08771 08772 /* Determine transfer context */ 08773 if (transferer->owner) /* Mimic behaviour in res_features.c */ 08774 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 08775 08776 /* By default, use the context in the channel sending the REFER */ 08777 if (ast_strlen_zero(transfer_context)) { 08778 transfer_context = S_OR(transferer->owner->macrocontext, 08779 S_OR(transferer->context, default_context)); 08780 } 08781 08782 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 08783 08784 /* Either an existing extension or the parking extension */ 08785 if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 08786 if (sip_debug_test_pvt(transferer)) { 08787 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 08788 } 08789 /* We are ready to transfer to the extension */ 08790 return 0; 08791 } 08792 if (sip_debug_test_pvt(transferer)) 08793 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 08794 08795 /* Failure, we can't find this extension */ 08796 return -1; 08797 }
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 8955 of file chan_sip.c.
References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
08956 { 08957 char *start; 08958 char *end; 08959 08960 start = strchr(input,':'); 08961 if (!start) { 08962 output[0] = '\0'; 08963 return 0; 08964 } 08965 start++; 08966 08967 /* we found "number" */ 08968 ast_copy_string(output,start,maxlen); 08969 output[maxlen-1] = '\0'; 08970 08971 end = strchr(output,'@'); 08972 if (end) 08973 *end = '\0'; 08974 else 08975 output[0] = '\0'; 08976 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 08977 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 08978 08979 return 0; 08980 }
static const char * get_sdp | ( | struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get a line from an SDP message body.
Definition at line 3946 of file chan_sip.c.
References get_sdp_iterate().
03947 { 03948 int dummy = 0; 03949 03950 return get_sdp_iterate(&dummy, req, name); 03951 }
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 3932 of file chan_sip.c.
References get_body_by_line(), len, and sip_request::line.
03933 { 03934 int len = strlen(name); 03935 03936 while (*start < req->sdp_end) { 03937 const char *r = get_body_by_line(req->line[(*start)++], name, len); 03938 if (r[0] != '\0') 03939 return r; 03940 } 03941 03942 return ""; 03943 }
static struct sip_pvt * get_sip_pvt_byid_locked | ( | const char * | callid, | |
const char * | totag, | |||
const char * | fromtag | |||
) | [static] |
Lock interface lock and find matching pvt lock
Definition at line 8588 of file chan_sip.c.
References ast_channel_trylock, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), 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().
08589 { 08590 struct sip_pvt *sip_pvt_ptr; 08591 08592 ast_mutex_lock(&iflock); 08593 08594 if (option_debug > 3 && totag) 08595 ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 08596 08597 /* Search interfaces and find the match */ 08598 for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 08599 if (!strcmp(sip_pvt_ptr->callid, callid)) { 08600 int match = 1; 08601 char *ourtag = sip_pvt_ptr->tag; 08602 08603 /* Go ahead and lock it (and its owner) before returning */ 08604 ast_mutex_lock(&sip_pvt_ptr->lock); 08605 08606 /* Check if tags match. If not, this is not the call we want 08607 (With a forking SIP proxy, several call legs share the 08608 call id, but have different tags) 08609 */ 08610 if (pedanticsipchecking && (strcmp(fromtag, sip_pvt_ptr->theirtag) || strcmp(totag, ourtag))) 08611 match = 0; 08612 08613 if (!match) { 08614 ast_mutex_unlock(&sip_pvt_ptr->lock); 08615 continue; 08616 } 08617 08618 if (option_debug > 3 && totag) 08619 ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n", 08620 ast_test_flag(&sip_pvt_ptr->flags[0], SIP_OUTGOING) ? "OUTGOING": "INCOMING", 08621 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 08622 08623 /* deadlock avoidance... */ 08624 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 08625 ast_mutex_unlock(&sip_pvt_ptr->lock); 08626 usleep(1); 08627 ast_mutex_lock(&sip_pvt_ptr->lock); 08628 } 08629 break; 08630 } 08631 } 08632 ast_mutex_unlock(&iflock); 08633 if (option_debug > 3 && !sip_pvt_ptr) 08634 ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 08635 return sip_pvt_ptr; 08636 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 12852 of file chan_sip.c.
References get_header(), strcasestr(), and strsep().
Referenced by find_call(), handle_request(), and handle_response().
12853 { 12854 const char *thetag; 12855 12856 if (!tagbuf) 12857 return NULL; 12858 tagbuf[0] = '\0'; /* reset the buffer */ 12859 thetag = get_header(req, header); 12860 thetag = strcasestr(thetag, ";tag="); 12861 if (thetag) { 12862 thetag += 5; 12863 ast_copy_string(tagbuf, thetag, tagbufsize); 12864 return strsep(&tagbuf, ";"); 12865 } 12866 return NULL; 12867 }
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 15483 of file chan_sip.c.
References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), ast_channel::flags, ast_variable::lineno, LOG_WARNING, ast_variable::name, SIP_CAN_REINVITE, SIP_CAN_REINVITE_NAT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_G726_NONSTANDARD, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, SIP_NAT_ROUTE, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_BUGGY_MWI, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NO, SIP_PROG_INBAND_YES, SIP_PROMISCREDIR, SIP_REINVITE, SIP_REINVITE_UPDATE, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USECLIENTCODE, strsep(), and ast_variable::value.
Referenced by build_peer(), build_user(), and reload_config().
15484 { 15485 int res = 1; 15486 static int dep_insecure_very = 0; 15487 static int dep_insecure_yes = 0; 15488 15489 if (!strcasecmp(v->name, "trustrpid")) { 15490 ast_set_flag(&mask[0], SIP_TRUSTRPID); 15491 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 15492 } else if (!strcasecmp(v->name, "sendrpid")) { 15493 ast_set_flag(&mask[0], SIP_SENDRPID); 15494 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 15495 } else if (!strcasecmp(v->name, "g726nonstandard")) { 15496 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 15497 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 15498 } else if (!strcasecmp(v->name, "useclientcode")) { 15499 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 15500 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 15501 } else if (!strcasecmp(v->name, "dtmfmode")) { 15502 ast_set_flag(&mask[0], SIP_DTMF); 15503 ast_clear_flag(&flags[0], SIP_DTMF); 15504 if (!strcasecmp(v->value, "inband")) 15505 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 15506 else if (!strcasecmp(v->value, "rfc2833")) 15507 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 15508 else if (!strcasecmp(v->value, "info")) 15509 ast_set_flag(&flags[0], SIP_DTMF_INFO); 15510 else if (!strcasecmp(v->value, "auto")) 15511 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 15512 else { 15513 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 15514 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 15515 } 15516 } else if (!strcasecmp(v->name, "nat")) { 15517 ast_set_flag(&mask[0], SIP_NAT); 15518 ast_clear_flag(&flags[0], SIP_NAT); 15519 if (!strcasecmp(v->value, "never")) 15520 ast_set_flag(&flags[0], SIP_NAT_NEVER); 15521 else if (!strcasecmp(v->value, "route")) 15522 ast_set_flag(&flags[0], SIP_NAT_ROUTE); 15523 else if (ast_true(v->value)) 15524 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 15525 else 15526 ast_set_flag(&flags[0], SIP_NAT_RFC3581); 15527 } else if (!strcasecmp(v->name, "canreinvite")) { 15528 ast_set_flag(&mask[0], SIP_REINVITE); 15529 ast_clear_flag(&flags[0], SIP_REINVITE); 15530 if (ast_true(v->value)) { 15531 ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT); 15532 } else if (!ast_false(v->value)) { 15533 char buf[64]; 15534 char *word, *next = buf; 15535 15536 ast_copy_string(buf, v->value, sizeof(buf)); 15537 while ((word = strsep(&next, ","))) { 15538 if (!strcasecmp(word, "update")) { 15539 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 15540 } else if (!strcasecmp(word, "nonat")) { 15541 ast_set_flag(&flags[0], SIP_CAN_REINVITE); 15542 ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT); 15543 } else { 15544 ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno); 15545 } 15546 } 15547 } 15548 } else if (!strcasecmp(v->name, "insecure")) { 15549 ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 15550 ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 15551 if (!strcasecmp(v->value, "very")) { 15552 ast_set_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 15553 if (!dep_insecure_very) { 15554 ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", v->lineno); 15555 dep_insecure_very = 1; 15556 } 15557 } 15558 else if (ast_true(v->value)) { 15559 ast_set_flag(&flags[0], SIP_INSECURE_PORT); 15560 if (!dep_insecure_yes) { 15561 ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", v->value, v->lineno); 15562 dep_insecure_yes = 1; 15563 } 15564 } 15565 else if (!ast_false(v->value)) { 15566 char buf[64]; 15567 char *word, *next; 15568 15569 ast_copy_string(buf, v->value, sizeof(buf)); 15570 next = buf; 15571 while ((word = strsep(&next, ","))) { 15572 if (!strcasecmp(word, "port")) 15573 ast_set_flag(&flags[0], SIP_INSECURE_PORT); 15574 else if (!strcasecmp(word, "invite")) 15575 ast_set_flag(&flags[0], SIP_INSECURE_INVITE); 15576 else 15577 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", v->value, v->lineno); 15578 } 15579 } 15580 } else if (!strcasecmp(v->name, "progressinband")) { 15581 ast_set_flag(&mask[0], SIP_PROG_INBAND); 15582 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 15583 if (ast_true(v->value)) 15584 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 15585 else if (strcasecmp(v->value, "never")) 15586 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 15587 } else if (!strcasecmp(v->name, "promiscredir")) { 15588 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 15589 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 15590 } else if (!strcasecmp(v->name, "videosupport")) { 15591 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 15592 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 15593 } else if (!strcasecmp(v->name, "allowoverlap")) { 15594 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 15595 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 15596 } else if (!strcasecmp(v->name, "allowsubscribe")) { 15597 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 15598 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 15599 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 15600 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 15601 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 15602 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 15603 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 15604 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 15605 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 15606 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 15607 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 15608 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 15609 #endif 15610 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 15611 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 15612 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 15613 } else if (!strcasecmp(v->name, "buggymwi")) { 15614 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 15615 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 15616 } else 15617 res = 0; 15618 15619 return res; 15620 }
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 13025 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().
13026 { 13027 struct ast_frame *f; 13028 int earlyreplace = 0; 13029 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 13030 struct ast_channel *c = p->owner; /* Our incoming call */ 13031 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 13032 struct ast_channel *targetcall; /* The bridge to the take-over target */ 13033 13034 /* Check if we're in ring state */ 13035 if (replacecall->_state == AST_STATE_RING) 13036 earlyreplace = 1; 13037 13038 /* Check if we have a bridge */ 13039 if (!(targetcall = ast_bridged_channel(replacecall))) { 13040 /* We have no bridge */ 13041 if (!earlyreplace) { 13042 if (option_debug > 1) 13043 ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 13044 oneleggedreplace = 1; 13045 } 13046 } 13047 if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING) 13048 ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n"); 13049 13050 if (option_debug > 3) { 13051 if (targetcall) 13052 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); 13053 else 13054 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 13055 } 13056 13057 if (ignore) { 13058 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 13059 /* We should answer something here. If we are here, the 13060 call we are replacing exists, so an accepted 13061 can't harm */ 13062 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13063 /* Do something more clever here */ 13064 ast_channel_unlock(c); 13065 ast_mutex_unlock(&p->refer->refer_call->lock); 13066 return 1; 13067 } 13068 if (!c) { 13069 /* What to do if no channel ??? */ 13070 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 13071 transmit_response_reliable(p, "503 Service Unavailable", req); 13072 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 13073 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13074 ast_mutex_unlock(&p->refer->refer_call->lock); 13075 return 1; 13076 } 13077 append_history(p, "Xfer", "INVITE/Replace received"); 13078 /* We have three channels to play with 13079 channel c: New incoming call 13080 targetcall: Call from PBX to target 13081 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 13082 replacecall: The owner of the previous 13083 We need to masq C into refer_call to connect to 13084 targetcall; 13085 If we are talking to internal audio stream, target call is null. 13086 */ 13087 13088 /* Fake call progress */ 13089 transmit_response(p, "100 Trying", req); 13090 ast_setstate(c, AST_STATE_RING); 13091 13092 /* Masquerade the new call into the referred call to connect to target call 13093 Targetcall is not touched by the masq */ 13094 13095 /* Answer the incoming call and set channel to UP state */ 13096 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13097 ast_setstate(c, AST_STATE_UP); 13098 13099 /* Stop music on hold and other generators */ 13100 ast_quiet_chan(replacecall); 13101 ast_quiet_chan(targetcall); 13102 if (option_debug > 3) 13103 ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 13104 /* Unlock clone, but not original (replacecall) */ 13105 ast_channel_unlock(c); 13106 13107 /* Unlock PVT */ 13108 ast_mutex_unlock(&p->refer->refer_call->lock); 13109 13110 /* Make sure that the masq does not free our PVT for the old call */ 13111 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 13112 13113 /* Prepare the masquerade - if this does not happen, we will be gone */ 13114 if(ast_channel_masquerade(replacecall, c)) 13115 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 13116 else if (option_debug > 3) 13117 ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 13118 13119 /* The masquerade will happen as soon as someone reads a frame from the channel */ 13120 13121 /* C should now be in place of replacecall */ 13122 /* ast_read needs to lock channel */ 13123 ast_channel_unlock(c); 13124 13125 if (earlyreplace || oneleggedreplace ) { 13126 /* Force the masq to happen */ 13127 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13128 ast_frfree(f); 13129 f = NULL; 13130 if (option_debug > 3) 13131 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from RING channel!\n"); 13132 } else { 13133 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from RING channel \n"); 13134 } 13135 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13136 ast_channel_unlock(replacecall); 13137 } else { /* Bridged call, UP channel */ 13138 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13139 /* Masq ok */ 13140 ast_frfree(f); 13141 f = NULL; 13142 if (option_debug > 2) 13143 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from channel! Masq done.\n"); 13144 } else { 13145 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from channel. Transfer failed\n"); 13146 } 13147 ast_channel_unlock(replacecall); 13148 } 13149 ast_mutex_unlock(&p->refer->refer_call->lock); 13150 13151 ast_setstate(c, AST_STATE_DOWN); 13152 if (option_debug > 3) { 13153 struct ast_channel *test; 13154 ast_log(LOG_DEBUG, "After transfer:----------------------------\n"); 13155 ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 13156 if (replacecall) 13157 ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 13158 if (p->owner) { 13159 ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 13160 test = ast_bridged_channel(p->owner); 13161 if (test) 13162 ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 13163 else 13164 ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n"); 13165 } else 13166 ast_log(LOG_DEBUG, " -- No channel yet \n"); 13167 ast_log(LOG_DEBUG, "End After transfer:----------------------------\n"); 13168 } 13169 13170 ast_channel_unlock(p->owner); /* Unlock new owner */ 13171 ast_mutex_unlock(&p->lock); /* Unlock SIP structure */ 13172 13173 /* The call should be down with no ast_channel, so hang it up */ 13174 c->tech_pvt = NULL; 13175 ast_hangup(c); 13176 return 0; 13177 }
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 14641 of file chan_sip.c.
References __sip_ack(), append_history, ast_inet_ntoa(), ast_log(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), check_pendings(), debug, DEFAULT_TRANS_TIMEOUT, error(), extract_uri(), FALSE, find_sdp(), FLAG_RESPONSE, sip_pvt::flags, get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), sip_request::header, sip_request::headers, cfsip_methods::id, sip_pvt::initreq, INV_TERMINATED, len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_request::method, option_debug, process_sdp(), sip_request::rlPart1, sip_request::rlPart2, SIP_ACK, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_debug_test_pvt(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_PKT_IGNORE_REQ, SIP_PKT_IGNORE_RESP, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_scheddestroy(), SIP_SUBSCRIBE, sip_pvt::tag, cfsip_methods::text, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and TRUE.
14642 { 14643 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 14644 relatively static */ 14645 const char *cmd; 14646 const char *cseq; 14647 const char *useragent; 14648 int seqno; 14649 int len; 14650 int ignore = FALSE; 14651 int respid; 14652 int res = 0; 14653 int debug = sip_debug_test_pvt(p); 14654 char *e; 14655 int error = 0; 14656 14657 /* Get Method and Cseq */ 14658 cseq = get_header(req, "Cseq"); 14659 cmd = req->header[0]; 14660 14661 /* Must have Cseq */ 14662 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 14663 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 14664 error = 1; 14665 } 14666 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 14667 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 14668 error = 1; 14669 } 14670 if (error) { 14671 if (!p->initreq.headers) /* New call */ 14672 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 14673 return -1; 14674 } 14675 /* Get the command XXX */ 14676 14677 cmd = req->rlPart1; 14678 e = req->rlPart2; 14679 14680 /* Save useragent of the client */ 14681 useragent = get_header(req, "User-Agent"); 14682 if (!ast_strlen_zero(useragent)) 14683 ast_string_field_set(p, useragent, useragent); 14684 14685 /* Find out SIP method for incoming request */ 14686 if (req->method == SIP_RESPONSE) { /* Response to our request */ 14687 /* Response to our request -- Do some sanity checks */ 14688 if (!p->initreq.headers) { 14689 if (option_debug) 14690 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 14691 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14692 return 0; 14693 } else if (p->ocseq && (p->ocseq < seqno)) { 14694 if (option_debug) 14695 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 14696 return -1; 14697 } else if (p->ocseq && (p->ocseq != seqno)) { 14698 /* ignore means "don't do anything with it" but still have to 14699 respond appropriately */ 14700 ignore = TRUE; 14701 ast_set_flag(req, SIP_PKT_IGNORE); 14702 ast_set_flag(req, SIP_PKT_IGNORE_RESP); 14703 append_history(p, "Ignore", "Ignoring this retransmit\n"); 14704 } else if (e) { 14705 e = ast_skip_blanks(e); 14706 if (sscanf(e, "%d %n", &respid, &len) != 1) { 14707 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 14708 } else { 14709 if (respid <= 0) { 14710 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 14711 return 0; 14712 } 14713 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 14714 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 14715 extract_uri(p, req); 14716 handle_response(p, respid, e + len, req, ignore, seqno); 14717 } 14718 } 14719 return 0; 14720 } 14721 14722 /* New SIP request coming in 14723 (could be new request in existing SIP dialog as well...) 14724 */ 14725 14726 p->method = req->method; /* Find out which SIP method they are using */ 14727 if (option_debug > 3) 14728 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 14729 14730 if (p->icseq && (p->icseq > seqno)) { 14731 if (option_debug) 14732 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 14733 if (req->method != SIP_ACK) 14734 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 14735 return -1; 14736 } else if (p->icseq && 14737 p->icseq == seqno && 14738 req->method != SIP_ACK && 14739 (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) { 14740 /* ignore means "don't do anything with it" but still have to 14741 respond appropriately. We do this if we receive a repeat of 14742 the last sequence number */ 14743 ignore = 2; 14744 ast_set_flag(req, SIP_PKT_IGNORE); 14745 ast_set_flag(req, SIP_PKT_IGNORE_REQ); 14746 if (option_debug > 2) 14747 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 14748 } 14749 14750 if (seqno >= p->icseq) 14751 /* Next should follow monotonically (but not necessarily 14752 incrementally -- thanks again to the genius authors of SIP -- 14753 increasing */ 14754 p->icseq = seqno; 14755 14756 /* Find their tag if we haven't got it */ 14757 if (ast_strlen_zero(p->theirtag)) { 14758 char tag[128]; 14759 14760 gettag(req, "From", tag, sizeof(tag)); 14761 ast_string_field_set(p, theirtag, tag); 14762 } 14763 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 14764 14765 if (pedanticsipchecking) { 14766 /* If this is a request packet without a from tag, it's not 14767 correct according to RFC 3261 */ 14768 /* Check if this a new request in a new dialog with a totag already attached to it, 14769 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 14770 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 14771 /* If this is a first request and it got a to-tag, it is not for us */ 14772 if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) { 14773 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 14774 /* Will cease to exist after ACK */ 14775 } else if (req->method != SIP_ACK) { 14776 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 14777 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14778 } 14779 return res; 14780 } 14781 } 14782 14783 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 14784 transmit_response(p, "400 Bad request", req); 14785 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14786 return -1; 14787 } 14788 14789 /* Handle various incoming SIP methods in requests */ 14790 switch (p->method) { 14791 case SIP_OPTIONS: 14792 res = handle_request_options(p, req); 14793 break; 14794 case SIP_INVITE: 14795 res = handle_request_invite(p, req, debug, seqno, sin, recount, e); 14796 break; 14797 case SIP_REFER: 14798 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 14799 break; 14800 case SIP_CANCEL: 14801 res = handle_request_cancel(p, req); 14802 break; 14803 case SIP_BYE: 14804 res = handle_request_bye(p, req); 14805 break; 14806 case SIP_MESSAGE: 14807 res = handle_request_message(p, req); 14808 break; 14809 case SIP_SUBSCRIBE: 14810 res = handle_request_subscribe(p, req, sin, seqno, e); 14811 break; 14812 case SIP_REGISTER: 14813 res = handle_request_register(p, req, sin, e); 14814 break; 14815 case SIP_INFO: 14816 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14817 ast_verbose("Receiving INFO!\n"); 14818 if (!ignore) 14819 handle_request_info(p, req); 14820 else /* if ignoring, transmit response */ 14821 transmit_response(p, "200 OK", req); 14822 break; 14823 case SIP_NOTIFY: 14824 res = handle_request_notify(p, req, sin, seqno, e); 14825 break; 14826 case SIP_ACK: 14827 /* Make sure we don't ignore this */ 14828 if (seqno == p->pendinginvite) { 14829 p->invitestate = INV_TERMINATED; 14830 p->pendinginvite = 0; 14831 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 14832 if (find_sdp(req)) { 14833 if (process_sdp(p, req)) 14834 return -1; 14835 } 14836 check_pendings(p); 14837 } 14838 /* Got an ACK that we did not match. Ignore silently */ 14839 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 14840 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14841 break; 14842 default: 14843 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 14844 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 14845 cmd, ast_inet_ntoa(p->sa.sin_addr)); 14846 /* If this is some new method, and we don't have a call, destroy it now */ 14847 if (!p->initreq.headers) 14848 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14849 break; 14850 } 14851 return res; 14852 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 14220 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().
14221 { 14222 struct ast_channel *c=NULL; 14223 int res; 14224 struct ast_channel *bridged_to; 14225 14226 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 14227 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 14228 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 14229 14230 p->invitestate = INV_TERMINATED; 14231 14232 copy_request(&p->initreq, req); 14233 check_via(p, req); 14234 sip_alreadygone(p); 14235 14236 /* Get RTCP quality before end of call */ 14237 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { 14238 char *audioqos, *videoqos; 14239 if (p->rtp) { 14240 audioqos = ast_rtp_get_quality(p->rtp, NULL); 14241 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 14242 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 14243 if (p->owner) 14244 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 14245 } 14246 if (p->vrtp) { 14247 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 14248 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 14249 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 14250 if (p->owner) 14251 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 14252 } 14253 } 14254 14255 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14256 14257 if (!ast_strlen_zero(get_header(req, "Also"))) { 14258 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 14259 ast_inet_ntoa(p->recv.sin_addr)); 14260 if (ast_strlen_zero(p->context)) 14261 ast_string_field_set(p, context, default_context); 14262 res = get_also_info(p, req); 14263 if (!res) { 14264 c = p->owner; 14265 if (c) { 14266 bridged_to = ast_bridged_channel(c); 14267 if (bridged_to) { 14268 /* Don't actually hangup here... */ 14269 ast_queue_control(c, AST_CONTROL_UNHOLD); 14270 ast_async_goto(bridged_to, p->context, p->refer->refer_to,1); 14271 } else 14272 ast_queue_hangup(p->owner); 14273 } 14274 } else { 14275 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 14276 if (p->owner) 14277 ast_queue_hangup(p->owner); 14278 } 14279 } else if (p->owner) { 14280 ast_queue_hangup(p->owner); 14281 if (option_debug > 2) 14282 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n"); 14283 } else { 14284 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14285 if (option_debug > 2) 14286 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n"); 14287 } 14288 transmit_response(p, "200 OK", req); 14289 14290 return 1; 14291 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 14132 of file chan_sip.c.
References ast_channel::_state, ast_log(), ast_queue_hangup(), AST_STATE_UP, check_via(), DEFAULT_TRANS_TIMEOUT, sip_pvt::initreq, INV_CANCELLED, sip_pvt::invitestate, sip_request::len, LOG_DEBUG, option_debug, sip_pvt::owner, sip_dual::req, sip_alreadygone(), sip_scheddestroy(), stop_media_flows(), transmit_response(), and transmit_response_reliable().
Referenced by handle_request().
14133 { 14134 14135 check_via(p, req); 14136 sip_alreadygone(p); 14137 p->invitestate = INV_CANCELLED; 14138 14139 if (p->owner && p->owner->_state == AST_STATE_UP) { 14140 /* This call is up, cancel is ignored, we need a bye */ 14141 transmit_response(p, "200 OK", req); 14142 if (option_debug) 14143 ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n"); 14144 return 0; 14145 } 14146 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14147 14148 if (p->owner) 14149 ast_queue_hangup(p->owner); 14150 else 14151 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14152 if (p->initreq.len > 0) { 14153 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 14154 transmit_response(p, "200 OK", req); 14155 return 1; 14156 } else { 14157 transmit_response(p, "481 Call Leg Does Not Exist", req); 14158 return 0; 14159 } 14160 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 10780 of file chan_sip.c.
References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), ast_queue_control(), ast_queue_frame(), ast_strlen_zero(), ast_test_flag, ast_verbose(), ast_channel::cdr, DEFAULT_TRANS_TIMEOUT, event, f, sip_pvt::flags, get_body(), get_header(), LOG_WARNING, sip_pvt::owner, sip_scheddestroy(), SIP_USECLIENTCODE, sipdebug, and transmit_response().
Referenced by handle_request().
10781 { 10782 char buf[1024]; 10783 unsigned int event; 10784 const char *c = get_header(req, "Content-Type"); 10785 10786 /* Need to check the media/type */ 10787 if (!strcasecmp(c, "application/dtmf-relay") || 10788 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 10789 unsigned int duration = 0; 10790 10791 /* Try getting the "signal=" part */ 10792 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 10793 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 10794 transmit_response(p, "200 OK", req); /* Should return error */ 10795 return; 10796 } else { 10797 ast_copy_string(buf, c, sizeof(buf)); 10798 } 10799 10800 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 10801 duration = atoi(c); 10802 if (!duration) 10803 duration = 100; /* 100 ms */ 10804 10805 if (!p->owner) { /* not a PBX call */ 10806 transmit_response(p, "481 Call leg/transaction does not exist", req); 10807 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10808 return; 10809 } 10810 10811 if (ast_strlen_zero(buf)) { 10812 transmit_response(p, "200 OK", req); 10813 return; 10814 } 10815 10816 if (buf[0] == '*') 10817 event = 10; 10818 else if (buf[0] == '#') 10819 event = 11; 10820 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 10821 event = 12 + buf[0] - 'A'; 10822 else 10823 event = atoi(buf); 10824 if (event == 16) { 10825 /* send a FLASH event */ 10826 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 10827 ast_queue_frame(p->owner, &f); 10828 if (sipdebug) 10829 ast_verbose("* DTMF-relay event received: FLASH\n"); 10830 } else { 10831 /* send a DTMF event */ 10832 struct ast_frame f = { AST_FRAME_DTMF, }; 10833 if (event < 10) { 10834 f.subclass = '0' + event; 10835 } else if (event < 11) { 10836 f.subclass = '*'; 10837 } else if (event < 12) { 10838 f.subclass = '#'; 10839 } else if (event < 16) { 10840 f.subclass = 'A' + (event - 12); 10841 } 10842 f.len = duration; 10843 ast_queue_frame(p->owner, &f); 10844 if (sipdebug) 10845 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 10846 } 10847 transmit_response(p, "200 OK", req); 10848 return; 10849 } else if (!strcasecmp(c, "application/media_control+xml")) { 10850 /* Eh, we'll just assume it's a fast picture update for now */ 10851 if (p->owner) 10852 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 10853 transmit_response(p, "200 OK", req); 10854 return; 10855 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 10856 /* Client code (from SNOM phone) */ 10857 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 10858 if (p->owner && p->owner->cdr) 10859 ast_cdr_setuserfield(p->owner, c); 10860 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 10861 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 10862 transmit_response(p, "200 OK", req); 10863 } else { 10864 transmit_response(p, "403 Unauthorized", req); 10865 } 10866 return; 10867 } 10868 /* Other type of INFO message, not really understood by Asterisk */ 10869 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 10870 10871 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 10872 transmit_response(p, "415 Unsupported media type", req); 10873 return; 10874 }
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 | |||
) | [static] |
Handle incoming INVITE request.
XXX: we should also check here does the other side supports t38 at all !!! XXX
Definition at line 13186 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, check_user(), check_via(), context, copy_request(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, error(), exten, extract_uri(), FALSE, find_sdp(), sip_pvt::flags, get_destination(), get_header(), get_rdnis(), get_sip_pvt_byid_locked(), handle_invite_replaces(), ast_channel::hangupcause, sip_request::headers, INC_CALL_LIMIT, sip_pvt::initreq, INV_COMPLETED, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::jointcapability, sip_pvt::lastinvite, sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, 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_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().
13187 { 13188 int res = 1; 13189 int gotdest; 13190 const char *p_replaces; 13191 char *replace_id = NULL; 13192 const char *required; 13193 unsigned int required_profile = 0; 13194 struct ast_channel *c = NULL; /* New channel */ 13195 13196 /* Find out what they support */ 13197 if (!p->sipoptions) { 13198 const char *supported = get_header(req, "Supported"); 13199 if (!ast_strlen_zero(supported)) 13200 parse_sip_options(p, supported); 13201 } 13202 13203 /* Find out what they require */ 13204 required = get_header(req, "Require"); 13205 if (!ast_strlen_zero(required)) { 13206 required_profile = parse_sip_options(NULL, required); 13207 if (required_profile && required_profile != SIP_OPT_REPLACES) { 13208 /* At this point we only support REPLACES */ 13209 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 13210 ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required); 13211 p->invitestate = INV_COMPLETED; 13212 if (!p->lastinvite) 13213 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13214 return -1; 13215 } 13216 } 13217 13218 /* Check if this is a loop */ 13219 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 13220 /* This is a call to ourself. Send ourselves an error code and stop 13221 processing immediately, as SIP really has no good mechanism for 13222 being able to call yourself */ 13223 /* If pedantic is on, we need to check the tags. If they're different, this is 13224 in fact a forked call through a SIP proxy somewhere. */ 13225 transmit_response(p, "482 Loop Detected", req); 13226 p->invitestate = INV_COMPLETED; 13227 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13228 return 0; 13229 } 13230 13231 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) { 13232 /* We already have a pending invite. Sorry. You are on hold. */ 13233 transmit_response(p, "491 Request Pending", req); 13234 if (option_debug) 13235 ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 13236 /* Don't destroy dialog here */ 13237 return 0; 13238 } 13239 13240 p_replaces = get_header(req, "Replaces"); 13241 if (!ast_strlen_zero(p_replaces)) { 13242 /* We have a replaces header */ 13243 char *ptr; 13244 char *fromtag = NULL; 13245 char *totag = NULL; 13246 char *start, *to; 13247 int error = 0; 13248 13249 if (p->owner) { 13250 if (option_debug > 2) 13251 ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 13252 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 13253 /* Do not destroy existing call */ 13254 return -1; 13255 } 13256 13257 if (sipdebug && option_debug > 2) 13258 ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 13259 /* Create a buffer we can manipulate */ 13260 replace_id = ast_strdupa(p_replaces); 13261 ast_uri_decode(replace_id); 13262 13263 if (!p->refer && !sip_refer_allocate(p)) { 13264 transmit_response(p, "500 Server Internal Error", req); 13265 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 13266 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13267 p->invitestate = INV_COMPLETED; 13268 return -1; 13269 } 13270 13271 /* Todo: (When we find phones that support this) 13272 if the replaces header contains ";early-only" 13273 we can only replace the call in early 13274 stage, not after it's up. 13275 13276 If it's not in early mode, 486 Busy. 13277 */ 13278 13279 /* Skip leading whitespace */ 13280 replace_id = ast_skip_blanks(replace_id); 13281 13282 start = replace_id; 13283 while ( (ptr = strsep(&start, ";")) ) { 13284 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 13285 if ( (to = strcasestr(ptr, "to-tag=") ) ) 13286 totag = to + 7; /* skip the keyword */ 13287 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 13288 fromtag = to + 9; /* skip the keyword */ 13289 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 13290 } 13291 } 13292 13293 if (sipdebug && option_debug > 3) 13294 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>"); 13295 13296 13297 /* Try to find call that we are replacing 13298 If we have a Replaces header, we need to cancel that call if we succeed with this call 13299 */ 13300 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 13301 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 13302 transmit_response(p, "481 Call Leg Does Not Exist (Replaces)", req); 13303 error = 1; 13304 } 13305 13306 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 13307 13308 /* The matched call is the call from the transferer to Asterisk . 13309 We want to bridge the bridged part of the call to the 13310 incoming invite, thus taking over the refered call */ 13311 13312 if (p->refer->refer_call == p) { 13313 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 13314 p->refer->refer_call = NULL; 13315 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 13316 error = 1; 13317 } 13318 13319 if (!error && !p->refer->refer_call->owner) { 13320 /* Oops, someting wrong anyway, no owner, no call */ 13321 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 13322 /* Check for better return code */ 13323 transmit_response(p, "481 Call Leg Does Not Exist (Replace)", req); 13324 error = 1; 13325 } 13326 13327 if (!error && p->refer->refer_call->owner->_state != AST_STATE_RING && p->refer->refer_call->owner->_state != AST_STATE_UP ) { 13328 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 13329 transmit_response(p, "603 Declined (Replaces)", req); 13330 error = 1; 13331 } 13332 13333 if (error) { /* Give up this dialog */ 13334 append_history(p, "Xfer", "INVITE/Replace Failed."); 13335 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13336 ast_mutex_unlock(&p->lock); 13337 if (p->refer->refer_call) { 13338 ast_mutex_unlock(&p->refer->refer_call->lock); 13339 ast_channel_unlock(p->refer->refer_call->owner); 13340 } 13341 p->invitestate = INV_COMPLETED; 13342 return -1; 13343 } 13344 } 13345 13346 13347 /* Check if this is an INVITE that sets up a new dialog or 13348 a re-invite in an existing dialog */ 13349 13350 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 13351 int newcall = (p->initreq.headers ? TRUE : FALSE); 13352 13353 sip_cancel_destroy(p); 13354 /* This also counts as a pending invite */ 13355 p->pendinginvite = seqno; 13356 check_via(p, req); 13357 13358 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 13359 if (!p->owner) { /* Not a re-invite */ 13360 if (debug) 13361 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 13362 if (newcall) 13363 append_history(p, "Invite", "New call: %s", p->callid); 13364 parse_ok_contact(p, req); 13365 } else { /* Re-invite on existing call */ 13366 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 13367 /* Handle SDP here if we already have an owner */ 13368 if (find_sdp(req)) { 13369 if (process_sdp(p, req)) { 13370 transmit_response(p, "488 Not acceptable here", req); 13371 if (!p->lastinvite) 13372 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13373 return -1; 13374 } 13375 } else { 13376 p->jointcapability = p->capability; 13377 if (option_debug) 13378 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 13379 } 13380 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */ 13381 append_history(p, "ReInv", "Re-invite received"); 13382 } 13383 } else if (debug) 13384 ast_verbose("Ignoring this INVITE request\n"); 13385 13386 13387 if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) { 13388 /* This is a new invite */ 13389 /* Handle authentication if this is our first invite */ 13390 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 13391 if (res == AUTH_CHALLENGE_SENT) { 13392 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 13393 return 0; 13394 } 13395 if (res < 0) { /* Something failed in authentication */ 13396 if (res == AUTH_FAKE_AUTH) { 13397 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 13398 transmit_fake_auth_response(p, req, 1); 13399 } else { 13400 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 13401 transmit_response_reliable(p, "403 Forbidden", req); 13402 } 13403 p->invitestate = INV_COMPLETED; 13404 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13405 ast_string_field_free(p, theirtag); 13406 return 0; 13407 } 13408 13409 /* We have a succesful authentication, process the SDP portion if there is one */ 13410 if (find_sdp(req)) { 13411 if (process_sdp(p, req)) { 13412 /* Unacceptable codecs */ 13413 transmit_response_reliable(p, "488 Not acceptable here", req); 13414 p->invitestate = INV_COMPLETED; 13415 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13416 if (option_debug) 13417 ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); 13418 return -1; 13419 } 13420 } else { /* No SDP in invite, call control session */ 13421 p->jointcapability = p->capability; 13422 if (option_debug > 1) 13423 ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n"); 13424 } 13425 13426 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 13427 /* This seems redundant ... see !p-owner above */ 13428 if (p->owner) 13429 ast_queue_frame(p->owner, &ast_null_frame); 13430 13431 13432 /* Initialize the context if it hasn't been already */ 13433 if (ast_strlen_zero(p->context)) 13434 ast_string_field_set(p, context, default_context); 13435 13436 13437 /* Check number of concurrent calls -vs- incoming limit HERE */ 13438 if (option_debug) 13439 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 13440 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 13441 if (res < 0) { 13442 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 13443 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 13444 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13445 p->invitestate = INV_COMPLETED; 13446 } 13447 return 0; 13448 } 13449 gotdest = get_destination(p, NULL); /* Get destination right away */ 13450 get_rdnis(p, NULL); /* Get redirect information */ 13451 extract_uri(p, req); /* Get the Contact URI */ 13452 build_contact(p); /* Build our contact header */ 13453 13454 if (p->rtp) { 13455 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 13456 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 13457 } 13458 13459 if (!replace_id && gotdest) { /* No matching extension found */ 13460 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 13461 transmit_response_reliable(p, "484 Address Incomplete", req); 13462 else 13463 transmit_response_reliable(p, "404 Not Found", req); 13464 p->invitestate = INV_COMPLETED; 13465 update_call_counter(p, DEC_CALL_LIMIT); 13466 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13467 return 0; 13468 } else { 13469 /* If no extension was specified, use the s one */ 13470 /* Basically for calling to IP/Host name only */ 13471 if (ast_strlen_zero(p->exten)) 13472 ast_string_field_set(p, exten, "s"); 13473 /* Initialize our tag */ 13474 13475 make_our_tag(p->tag, sizeof(p->tag)); 13476 /* First invitation - create the channel */ 13477 c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL)); 13478 *recount = 1; 13479 13480 /* Save Record-Route for any later requests we make on this dialogue */ 13481 build_route(p, req, 0); 13482 13483 if (c) { 13484 /* Pre-lock the call */ 13485 ast_channel_lock(c); 13486 } 13487 } 13488 } else { 13489 if (option_debug > 1 && sipdebug) { 13490 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 13491 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 13492 else 13493 ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 13494 } 13495 c = p->owner; 13496 } 13497 13498 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 13499 p->lastinvite = seqno; 13500 13501 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 13502 /* Go and take over the target call */ 13503 if (sipdebug && option_debug > 3) 13504 ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid); 13505 return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin); 13506 } 13507 13508 13509 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 13510 switch(c->_state) { 13511 case AST_STATE_DOWN: 13512 if (option_debug > 1) 13513 ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name); 13514 transmit_response(p, "100 Trying", req); 13515 p->invitestate = INV_PROCEEDING; 13516 ast_setstate(c, AST_STATE_RING); 13517 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 13518 enum ast_pbx_result res; 13519 13520 res = ast_pbx_start(c); 13521 13522 switch(res) { 13523 case AST_PBX_FAILED: 13524 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 13525 p->invitestate = INV_COMPLETED; 13526 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13527 transmit_response(p, "503 Unavailable", req); 13528 else 13529 transmit_response_reliable(p, "503 Unavailable", req); 13530 break; 13531 case AST_PBX_CALL_LIMIT: 13532 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 13533 p->invitestate = INV_COMPLETED; 13534 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13535 transmit_response(p, "480 Temporarily Unavailable", req); 13536 else 13537 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 13538 break; 13539 case AST_PBX_SUCCESS: 13540 /* nothing to do */ 13541 break; 13542 } 13543 13544 if (res) { 13545 13546 /* Unlock locks so ast_hangup can do its magic */ 13547 ast_mutex_unlock(&c->lock); 13548 ast_mutex_unlock(&p->lock); 13549 ast_hangup(c); 13550 ast_mutex_lock(&p->lock); 13551 c = NULL; 13552 } 13553 } else { /* Pickup call in call group */ 13554 ast_channel_unlock(c); 13555 if (ast_pickup_call(c)) { 13556 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 13557 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13558 transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */ 13559 else 13560 transmit_response_reliable(p, "503 Unavailable", req); 13561 sip_alreadygone(p); 13562 /* Unlock locks so ast_hangup can do its magic */ 13563 ast_mutex_unlock(&p->lock); 13564 c->hangupcause = AST_CAUSE_CALL_REJECTED; 13565 } else { 13566 ast_mutex_unlock(&p->lock); 13567 ast_setstate(c, AST_STATE_DOWN); 13568 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 13569 } 13570 p->invitestate = INV_COMPLETED; 13571 ast_hangup(c); 13572 ast_mutex_lock(&p->lock); 13573 c = NULL; 13574 } 13575 break; 13576 case AST_STATE_RING: 13577 transmit_response(p, "100 Trying", req); 13578 p->invitestate = INV_PROCEEDING; 13579 break; 13580 case AST_STATE_RINGING: 13581 transmit_response(p, "180 Ringing", req); 13582 p->invitestate = INV_PROCEEDING; 13583 break; 13584 case AST_STATE_UP: 13585 if (option_debug > 1) 13586 ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); 13587 13588 if (p->t38.state == T38_PEER_REINVITE) { 13589 struct ast_channel *bridgepeer = NULL; 13590 struct sip_pvt *bridgepvt = NULL; 13591 13592 if ((bridgepeer = ast_bridged_channel(p->owner))) { 13593 /* 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*/ 13594 /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */ 13595 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 13596 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 13597 if (bridgepvt->t38.state == T38_DISABLED) { 13598 if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */ 13599 /* Send re-invite to the bridged channel */ 13600 sip_handle_t38_reinvite(bridgepeer, p, 1); 13601 } else { /* Something is wrong with peers udptl struct */ 13602 ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n"); 13603 ast_mutex_lock(&bridgepvt->lock); 13604 bridgepvt->t38.state = T38_DISABLED; 13605 ast_mutex_unlock(&bridgepvt->lock); 13606 if (option_debug > 1) 13607 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name); 13608 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13609 transmit_response(p, "488 Not acceptable here", req); 13610 else 13611 transmit_response_reliable(p, "488 Not acceptable here", req); 13612 13613 } 13614 } else { 13615 /* The other side is already setup for T.38 most likely so we need to acknowledge this too */ 13616 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 13617 p->t38.state = T38_ENABLED; 13618 if (option_debug) 13619 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13620 } 13621 } else { 13622 /* Other side is not a SIP channel */ 13623 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13624 transmit_response(p, "488 Not acceptable here", req); 13625 else 13626 transmit_response_reliable(p, "488 Not acceptable here", req); 13627 p->t38.state = T38_DISABLED; 13628 if (option_debug > 1) 13629 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13630 13631 if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */ 13632 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13633 } 13634 } else { 13635 /* we are not bridged in a call */ 13636 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 13637 p->t38.state = T38_ENABLED; 13638 if (option_debug) 13639 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13640 } 13641 } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */ 13642 int sendok = TRUE; 13643 13644 /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */ 13645 /* so handle it here (re-invite other party to RTP) */ 13646 struct ast_channel *bridgepeer = NULL; 13647 struct sip_pvt *bridgepvt = NULL; 13648 if ((bridgepeer = ast_bridged_channel(p->owner))) { 13649 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 13650 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 13651 /* Does the bridged peer have T38 ? */ 13652 if (bridgepvt->t38.state == T38_ENABLED) { 13653 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 13654 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 13655 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13656 transmit_response(p, "488 Not Acceptable Here (unsupported)", req); 13657 else 13658 transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req); 13659 sendok = FALSE; 13660 } 13661 /* No bridged peer with T38 enabled*/ 13662 } 13663 } 13664 /* Respond to normal re-invite */ 13665 if (sendok) 13666 transmit_response_with_sdp(p, "200 OK", req, ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_CRITICAL); 13667 } 13668 p->invitestate = INV_TERMINATED; 13669 break; 13670 default: 13671 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 13672 transmit_response(p, "100 Trying", req); 13673 break; 13674 } 13675 } else { 13676 if (p && (p->autokillid == -1)) { 13677 const char *msg; 13678 13679 if (!p->jointcapability) 13680 msg = "488 Not Acceptable Here (codec error)"; 13681 else { 13682 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 13683 msg = "503 Unavailable"; 13684 } 13685 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13686 transmit_response(p, msg, req); 13687 else 13688 transmit_response_reliable(p, msg, req); 13689 p->invitestate = INV_COMPLETED; 13690 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13691 } 13692 } 13693 return res; 13694 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 14294 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().
14295 { 14296 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14297 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14298 ast_verbose("Receiving message!\n"); 14299 receive_message(p, req); 14300 } else 14301 transmit_response(p, "202 Accepted", req); 14302 return 1; 14303 }
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 12870 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().
12871 { 12872 /* This is mostly a skeleton for future improvements */ 12873 /* Mostly created to return proper answers on notifications on outbound REFER's */ 12874 int res = 0; 12875 const char *event = get_header(req, "Event"); 12876 char *eventid = NULL; 12877 char *sep; 12878 12879 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 12880 *sep++ = '\0'; 12881 eventid = sep; 12882 } 12883 12884 if (option_debug > 1 && sipdebug) 12885 ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event); 12886 12887 if (strcmp(event, "refer")) { 12888 /* We don't understand this event. */ 12889 /* Here's room to implement incoming voicemail notifications :-) */ 12890 transmit_response(p, "489 Bad event", req); 12891 res = -1; 12892 } else { 12893 /* Save nesting depth for now, since there might be other events we will 12894 support in the future */ 12895 12896 /* Handle REFER notifications */ 12897 12898 char buf[1024]; 12899 char *cmd, *code; 12900 int respcode; 12901 int success = TRUE; 12902 12903 /* EventID for each transfer... EventID is basically the REFER cseq 12904 12905 We are getting notifications on a call that we transfered 12906 We should hangup when we are getting a 200 OK in a sipfrag 12907 Check if we have an owner of this event */ 12908 12909 /* Check the content type */ 12910 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 12911 /* We need a sipfrag */ 12912 transmit_response(p, "400 Bad request", req); 12913 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12914 return -1; 12915 } 12916 12917 /* Get the text of the attachment */ 12918 if (get_msg_text(buf, sizeof(buf), req)) { 12919 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 12920 transmit_response(p, "400 Bad request", req); 12921 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12922 return -1; 12923 } 12924 12925 /* 12926 From the RFC... 12927 A minimal, but complete, implementation can respond with a single 12928 NOTIFY containing either the body: 12929 SIP/2.0 100 Trying 12930 12931 if the subscription is pending, the body: 12932 SIP/2.0 200 OK 12933 if the reference was successful, the body: 12934 SIP/2.0 503 Service Unavailable 12935 if the reference failed, or the body: 12936 SIP/2.0 603 Declined 12937 12938 if the REFER request was accepted before approval to follow the 12939 reference could be obtained and that approval was subsequently denied 12940 (see Section 2.4.7). 12941 12942 If there are several REFERs in the same dialog, we need to 12943 match the ID of the event header... 12944 */ 12945 if (option_debug > 2) 12946 ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 12947 cmd = ast_skip_blanks(buf); 12948 code = cmd; 12949 /* We are at SIP/2.0 */ 12950 while(*code && (*code > 32)) { /* Search white space */ 12951 code++; 12952 } 12953 *code++ = '\0'; 12954 code = ast_skip_blanks(code); 12955 sep = code; 12956 sep++; 12957 while(*sep && (*sep > 32)) { /* Search white space */ 12958 sep++; 12959 } 12960 *sep++ = '\0'; /* Response string */ 12961 respcode = atoi(code); 12962 switch (respcode) { 12963 case 100: /* Trying: */ 12964 case 101: /* dialog establishment */ 12965 /* Don't do anything yet */ 12966 break; 12967 case 183: /* Ringing: */ 12968 /* Don't do anything yet */ 12969 break; 12970 case 200: /* OK: The new call is up, hangup this call */ 12971 /* Hangup the call that we are replacing */ 12972 break; 12973 case 301: /* Moved permenantly */ 12974 case 302: /* Moved temporarily */ 12975 /* Do we get the header in the packet in this case? */ 12976 success = FALSE; 12977 break; 12978 case 503: /* Service Unavailable: The new call failed */ 12979 /* Cancel transfer, continue the call */ 12980 success = FALSE; 12981 break; 12982 case 603: /* Declined: Not accepted */ 12983 /* Cancel transfer, continue the current call */ 12984 success = FALSE; 12985 break; 12986 } 12987 if (!success) { 12988 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 12989 } 12990 12991 /* Confirm that we received this packet */ 12992 transmit_response(p, "200 OK", req); 12993 }; 12994 12995 if (!p->lastinvite) 12996 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12997 12998 return res; 12999 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming OPTIONS request.
Definition at line 13002 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().
13003 { 13004 int res; 13005 13006 res = get_destination(p, req); 13007 build_contact(p); 13008 /* XXX Should we authenticate OPTIONS? XXX */ 13009 if (ast_strlen_zero(p->context)) 13010 ast_string_field_set(p, context, default_context); 13011 if (res < 0) 13012 transmit_response_with_allow(p, "404 Not Found", req, 0); 13013 else 13014 transmit_response_with_allow(p, "200 OK", req, 0); 13015 /* Destroy if this OPTIONS was the opening request, but not if 13016 it's in the middle of a normal call flow. */ 13017 if (!p->lastinvite) 13018 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13019 13020 return res; 13021 }
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 13859 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().
13860 { 13861 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 13862 /* Chan2: Call between asterisk and transferee */ 13863 13864 int res = 0; 13865 13866 if (ast_test_flag(req, SIP_PKT_DEBUG)) 13867 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"); 13868 13869 if (!p->owner) { 13870 /* This is a REFER outside of an existing SIP dialog */ 13871 /* We can't handle that, so decline it */ 13872 if (option_debug > 2) 13873 ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 13874 transmit_response(p, "603 Declined (No dialog)", req); 13875 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 13876 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 13877 sip_alreadygone(p); 13878 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13879 } 13880 return 0; 13881 } 13882 13883 13884 /* Check if transfer is allowed from this device */ 13885 if (p->allowtransfer == TRANSFER_CLOSED ) { 13886 /* Transfer not allowed, decline */ 13887 transmit_response(p, "603 Declined (policy)", req); 13888 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 13889 /* Do not destroy SIP session */ 13890 return 0; 13891 } 13892 13893 if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 13894 /* Already have a pending REFER */ 13895 transmit_response(p, "491 Request pending", req); 13896 append_history(p, "Xfer", "Refer failed. Request pending."); 13897 return 0; 13898 } 13899 13900 /* Allocate memory for call transfer data */ 13901 if (!p->refer && !sip_refer_allocate(p)) { 13902 transmit_response(p, "500 Internal Server Error", req); 13903 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 13904 return -3; 13905 } 13906 13907 res = get_refer_info(p, req); /* Extract headers */ 13908 13909 p->refer->status = REFER_SENT; 13910 13911 if (res != 0) { 13912 switch (res) { 13913 case -2: /* Syntax error */ 13914 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 13915 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 13916 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 13917 ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 13918 break; 13919 case -3: 13920 transmit_response(p, "603 Declined (Non sip: uri)", req); 13921 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 13922 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 13923 ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n"); 13924 break; 13925 default: 13926 /* Refer-to extension not found, fake a failed transfer */ 13927 transmit_response(p, "202 Accepted", req); 13928 append_history(p, "Xfer", "Refer failed. Bad extension."); 13929 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 13930 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 13931 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 13932 ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 13933 break; 13934 } 13935 return 0; 13936 } 13937 if (ast_strlen_zero(p->context)) 13938 ast_string_field_set(p, context, default_context); 13939 13940 /* If we do not support SIP domains, all transfers are local */ 13941 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 13942 p->refer->localtransfer = 1; 13943 if (sipdebug && option_debug > 2) 13944 ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 13945 } else if (AST_LIST_EMPTY(&domain_list)) { 13946 /* This PBX don't bother with SIP domains, so all transfers are local */ 13947 p->refer->localtransfer = 1; 13948 } else 13949 if (sipdebug && option_debug > 2) 13950 ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 13951 13952 /* Is this a repeat of a current request? Ignore it */ 13953 /* Don't know what else to do right now. */ 13954 if (ignore) 13955 return res; 13956 13957 /* If this is a blind transfer, we have the following 13958 channels to work with: 13959 - chan1, chan2: The current call between transferer and transferee (2 channels) 13960 - target_channel: A new call from the transferee to the target (1 channel) 13961 We need to stay tuned to what happens in order to be able 13962 to bring back the call to the transferer */ 13963 13964 /* If this is a attended transfer, we should have all call legs within reach: 13965 - chan1, chan2: The call between the transferer and transferee (2 channels) 13966 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 13967 We want to bridge chan2 with targetcall_pvt! 13968 13969 The replaces call id in the refer message points 13970 to the call leg between Asterisk and the transferer. 13971 So we need to connect the target and the transferee channel 13972 and hangup the two other channels silently 13973 13974 If the target is non-local, the call ID could be on a remote 13975 machine and we need to send an INVITE with replaces to the 13976 target. We basically handle this as a blind transfer 13977 and let the sip_call function catch that we need replaces 13978 header in the INVITE. 13979 */ 13980 13981 13982 /* Get the transferer's channel */ 13983 current.chan1 = p->owner; 13984 13985 /* Find the other part of the bridge (2) - transferee */ 13986 current.chan2 = ast_bridged_channel(current.chan1); 13987 13988 if (sipdebug && option_debug > 2) 13989 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>"); 13990 13991 if (!current.chan2 && !p->refer->attendedtransfer) { 13992 /* No bridged channel, propably IVR or echo or similar... */ 13993 /* Guess we should masquerade or something here */ 13994 /* Until we figure it out, refuse transfer of such calls */ 13995 if (sipdebug && option_debug > 2) 13996 ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n"); 13997 p->refer->status = REFER_FAILED; 13998 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 13999 transmit_response(p, "603 Declined", req); 14000 return -1; 14001 } 14002 14003 if (current.chan2) { 14004 if (sipdebug && option_debug > 3) 14005 ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 14006 14007 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 14008 } 14009 14010 ast_set_flag(&p->flags[0], SIP_GOTREFER); 14011 14012 /* Attended transfer: Find all call legs and bridge transferee with target*/ 14013 if (p->refer->attendedtransfer) { 14014 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 14015 return res; /* We're done with the transfer */ 14016 /* Fall through for remote transfers that we did not find locally */ 14017 if (sipdebug && option_debug > 3) 14018 ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 14019 /* Fallthrough if we can't find the call leg internally */ 14020 } 14021 14022 14023 /* Parking a call */ 14024 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 14025 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 14026 *nounlock = 1; 14027 ast_channel_unlock(current.chan1); 14028 copy_request(¤t.req, req); 14029 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14030 p->refer->status = REFER_200OK; 14031 append_history(p, "Xfer", "REFER to call parking."); 14032 if (sipdebug && option_debug > 3) 14033 ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 14034 sip_park(current.chan2, current.chan1, req, seqno); 14035 return res; 14036 } 14037 14038 /* Blind transfers and remote attended xfers */ 14039 transmit_response(p, "202 Accepted", req); 14040 14041 if (current.chan1 && current.chan2) { 14042 if (option_debug > 2) 14043 ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name); 14044 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 14045 } 14046 if (current.chan2) { 14047 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 14048 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 14049 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 14050 /* One for the new channel */ 14051 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 14052 /* Attended transfer to remote host, prepare headers for the INVITE */ 14053 if (p->refer->referred_by) 14054 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 14055 } 14056 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 14057 if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) { 14058 char tempheader[BUFSIZ]; 14059 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 14060 p->refer->replaces_callid_totag ? ";to-tag=" : "", 14061 p->refer->replaces_callid_totag, 14062 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 14063 p->refer->replaces_callid_fromtag); 14064 if (current.chan2) 14065 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 14066 } 14067 /* Must release lock now, because it will not longer 14068 be accessible after the transfer! */ 14069 *nounlock = 1; 14070 ast_channel_unlock(current.chan1); 14071 ast_channel_unlock(current.chan2); 14072 14073 /* Connect the call */ 14074 14075 /* FAKE ringing if not attended transfer */ 14076 if (!p->refer->attendedtransfer) 14077 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 14078 14079 /* For blind transfer, this will lead to a new call */ 14080 /* For attended transfer to remote host, this will lead to 14081 a new SIP call with a replaces header, if the dial plan allows it 14082 */ 14083 if (!current.chan2) { 14084 /* We have no bridge, so we're talking with Asterisk somehow */ 14085 /* We need to masquerade this call */ 14086 /* What to do to fix this situation: 14087 * Set up the new call in a new channel 14088 * Let the new channel masq into this channel 14089 Please add that code here :-) 14090 */ 14091 p->refer->status = REFER_FAILED; 14092 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 14093 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14094 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 14095 return -1; 14096 } 14097 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14098 14099 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 14100 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 14101 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 14102 14103 if (!res) { 14104 /* Success - we have a new channel */ 14105 if (option_debug > 2) 14106 ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 14107 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 14108 if (p->refer->localtransfer) 14109 p->refer->status = REFER_200OK; 14110 if (p->owner) 14111 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14112 append_history(p, "Xfer", "Refer succeeded."); 14113 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14114 /* Do not hangup call, the other side do that when we say 200 OK */ 14115 /* We could possibly implement a timer here, auto congestion */ 14116 res = 0; 14117 } else { 14118 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 14119 if (option_debug > 2) 14120 ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 14121 append_history(p, "Xfer", "Refer failed."); 14122 /* Failure of some kind */ 14123 p->refer->status = REFER_FAILED; 14124 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 14125 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14126 res = -1; 14127 } 14128 return res; 14129 }
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 14597 of file chan_sip.c.
References append_history, ast_inet_ntoa(), ast_log(), ast_test_flag, ast_verbose(), AUTH_NOT_FOUND, 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().
14598 { 14599 enum check_auth_result res; 14600 14601 /* Use this as the basis */ 14602 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14603 ast_verbose("Using latest REGISTER request as basis request\n"); 14604 copy_request(&p->initreq, req); 14605 check_via(p, req); 14606 if ((res = register_verify(p, sin, req, e)) < 0) { 14607 const char *reason = ""; 14608 14609 switch (res) { 14610 case AUTH_SECRET_FAILED: 14611 reason = "Wrong password"; 14612 break; 14613 case AUTH_USERNAME_MISMATCH: 14614 reason = "Username/auth name mismatch"; 14615 break; 14616 case AUTH_NOT_FOUND: 14617 reason = "No matching peer found"; 14618 break; 14619 case AUTH_UNKNOWN_DOMAIN: 14620 reason = "Not a local domain"; 14621 break; 14622 default: 14623 break; 14624 } 14625 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 14626 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 14627 reason); 14628 } 14629 if (res < 1) { 14630 /* Destroy the session, but keep us around for just a bit in case they don't 14631 get our 200 OK */ 14632 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14633 } 14634 append_history(p, "RegRequest", "%s : Account %s", res ? "Failed": "Succeeded", get_header(req, "To")); 14635 return res; 14636 }
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 14306 of file chan_sip.c.
References append_history, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), 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, 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().
14307 { 14308 int gotdest; 14309 int res = 0; 14310 int firststate = AST_EXTENSION_REMOVED; 14311 struct sip_peer *authpeer = NULL; 14312 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 14313 const char *accept = get_header(req, "Accept"); 14314 int resubscribe = (p->subscribed != NONE); 14315 char *temp, *event; 14316 14317 if (p->initreq.headers) { 14318 /* We already have a dialog */ 14319 if (p->initreq.method != SIP_SUBSCRIBE) { 14320 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 14321 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 14322 transmit_response(p, "403 Forbidden (within dialog)", req); 14323 /* Do not destroy session, since we will break the call if we do */ 14324 if (option_debug) 14325 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); 14326 return 0; 14327 } else if (ast_test_flag(req, SIP_PKT_DEBUG)) { 14328 if (option_debug) { 14329 if (resubscribe) 14330 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 14331 else 14332 ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid); 14333 } 14334 } 14335 } 14336 14337 /* Check if we have a global disallow setting on subscriptions. 14338 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 14339 */ 14340 if (!global_allowsubscribe) { 14341 transmit_response(p, "403 Forbidden (policy)", req); 14342 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14343 return 0; 14344 } 14345 14346 if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */ 14347 /* Use this as the basis */ 14348 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14349 ast_verbose("Creating new subscription\n"); 14350 14351 copy_request(&p->initreq, req); 14352 check_via(p, req); 14353 } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE)) 14354 ast_verbose("Ignoring this SUBSCRIBE request\n"); 14355 14356 /* Find parameters to Event: header value and remove them for now */ 14357 if (ast_strlen_zero(eventheader)) { 14358 transmit_response(p, "489 Bad Event", req); 14359 if (option_debug > 1) 14360 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n"); 14361 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14362 return 0; 14363 } 14364 14365 if ( (strchr(eventheader, ';'))) { 14366 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 14367 temp = strchr(event, ';'); 14368 *temp = '\0'; /* Remove any options for now */ 14369 /* We might need to use them later :-) */ 14370 } else 14371 event = (char *) eventheader; /* XXX is this legal ? */ 14372 14373 /* Handle authentication */ 14374 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 14375 /* if an authentication response was sent, we are done here */ 14376 if (res == AUTH_CHALLENGE_SENT) { 14377 if (authpeer) 14378 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14379 return 0; 14380 } 14381 if (res < 0) { 14382 if (res == AUTH_FAKE_AUTH) { 14383 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 14384 transmit_fake_auth_response(p, req, 1); 14385 } else { 14386 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 14387 transmit_response_reliable(p, "403 Forbidden", req); 14388 } 14389 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14390 if (authpeer) 14391 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14392 return 0; 14393 } 14394 14395 /* Check if this user/peer is allowed to subscribe at all */ 14396 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 14397 transmit_response(p, "403 Forbidden (policy)", req); 14398 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14399 if (authpeer) 14400 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14401 return 0; 14402 } 14403 14404 /* Get destination right away */ 14405 gotdest = get_destination(p, NULL); 14406 14407 /* Initialize the context if it hasn't been already; 14408 note this is done _after_ handling any domain lookups, 14409 because the context specified there is for calls, not 14410 subscriptions 14411 */ 14412 if (!ast_strlen_zero(p->subscribecontext)) 14413 ast_string_field_set(p, context, p->subscribecontext); 14414 else if (ast_strlen_zero(p->context)) 14415 ast_string_field_set(p, context, default_context); 14416 14417 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 14418 parse_ok_contact(p, req); 14419 14420 build_contact(p); 14421 if (gotdest) { 14422 transmit_response(p, "404 Not Found", req); 14423 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14424 if (authpeer) 14425 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14426 return 0; 14427 } 14428 14429 /* Initialize tag for new subscriptions */ 14430 if (ast_strlen_zero(p->tag)) 14431 make_our_tag(p->tag, sizeof(p->tag)); 14432 14433 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 14434 if (authpeer) /* No need for authpeer here */ 14435 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14436 14437 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 14438 /* Polycom phones only handle xpidf+xml, even if they say they can 14439 handle pidf+xml as well 14440 */ 14441 if (strstr(p->useragent, "Polycom")) { 14442 p->subscribed = XPIDF_XML; 14443 } else if (strstr(accept, "application/pidf+xml")) { 14444 p->subscribed = PIDF_XML; /* RFC 3863 format */ 14445 } else if (strstr(accept, "application/dialog-info+xml")) { 14446 p->subscribed = DIALOG_INFO_XML; 14447 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 14448 } else if (strstr(accept, "application/cpim-pidf+xml")) { 14449 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 14450 } else if (strstr(accept, "application/xpidf+xml")) { 14451 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 14452 } else if (ast_strlen_zero(accept)) { 14453 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 14454 transmit_response(p, "489 Bad Event", req); 14455 14456 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 14457 p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 14458 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14459 return 0; 14460 } 14461 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 14462 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 14463 } else { 14464 /* Can't find a format for events that we know about */ 14465 char mybuf[200]; 14466 snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept); 14467 transmit_response(p, mybuf, req); 14468 14469 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 14470 accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 14471 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14472 return 0; 14473 } 14474 } else if (!strcmp(event, "message-summary")) { 14475 if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) { 14476 /* Format requested that we do not support */ 14477 transmit_response(p, "406 Not Acceptable", req); 14478 if (option_debug > 1) 14479 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept); 14480 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14481 if (authpeer) /* No need for authpeer here */ 14482 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14483 return 0; 14484 } 14485 /* Looks like they actually want a mailbox status 14486 This version of Asterisk supports mailbox subscriptions 14487 The subscribed URI needs to exist in the dial plan 14488 In most devices, this is configurable to the voicemailmain extension you use 14489 */ 14490 if (!authpeer || ast_strlen_zero(authpeer->mailbox)) { 14491 transmit_response(p, "404 Not found (no mailbox)", req); 14492 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14493 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 14494 if (authpeer) /* No need for authpeer here */ 14495 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14496 return 0; 14497 } 14498 14499 p->subscribed = MWI_NOTIFICATION; 14500 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 14501 /* We only allow one subscription per peer */ 14502 sip_destroy(authpeer->mwipvt); 14503 authpeer->mwipvt = p; /* Link from peer to pvt */ 14504 p->relatedpeer = authpeer; /* Link from pvt to peer */ 14505 } else { /* At this point, Asterisk does not understand the specified event */ 14506 transmit_response(p, "489 Bad Event", req); 14507 if (option_debug > 1) 14508 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 14509 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14510 if (authpeer) /* No need for authpeer here */ 14511 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14512 return 0; 14513 } 14514 14515 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) 14516 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 14517 14518 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 14519 p->lastinvite = seqno; 14520 if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 14521 p->expiry = atoi(get_header(req, "Expires")); 14522 14523 /* check if the requested expiry-time is within the approved limits from sip.conf */ 14524 if (p->expiry > max_expiry) 14525 p->expiry = max_expiry; 14526 if (p->expiry < min_expiry && p->expiry > 0) 14527 p->expiry = min_expiry; 14528 14529 if (sipdebug || option_debug > 1) { 14530 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 14531 ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox); 14532 else 14533 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 14534 } 14535 if (p->autokillid > -1) 14536 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 14537 if (p->expiry > 0) 14538 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 14539 14540 if (p->subscribed == MWI_NOTIFICATION) { 14541 transmit_response(p, "200 OK", req); 14542 if (p->relatedpeer) { /* Send first notification */ 14543 ASTOBJ_WRLOCK(p->relatedpeer); 14544 sip_send_mwi_to_peer(p->relatedpeer); 14545 ASTOBJ_UNLOCK(p->relatedpeer); 14546 } 14547 } else { 14548 struct sip_pvt *p_old; 14549 14550 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 14551 14552 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)); 14553 transmit_response(p, "404 Not found", req); 14554 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14555 return 0; 14556 } 14557 14558 transmit_response(p, "200 OK", req); 14559 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 14560 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 14561 /* hide the 'complete' exten/context in the refer_to field for later display */ 14562 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 14563 14564 /* remove any old subscription from this peer for the same exten/context, 14565 as the peer has obviously forgotten about it and it's wasteful to wait 14566 for it to expire and send NOTIFY messages to the peer only to have them 14567 ignored (or generate errors) 14568 */ 14569 ast_mutex_lock(&iflock); 14570 for (p_old = iflist; p_old; p_old = p_old->next) { 14571 if (p_old == p) 14572 continue; 14573 if (p_old->initreq.method != SIP_SUBSCRIBE) 14574 continue; 14575 if (p_old->subscribed == NONE) 14576 continue; 14577 ast_mutex_lock(&p_old->lock); 14578 if (!strcmp(p_old->username, p->username)) { 14579 if (!strcmp(p_old->exten, p->exten) && 14580 !strcmp(p_old->context, p->context)) { 14581 ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY); 14582 ast_mutex_unlock(&p_old->lock); 14583 break; 14584 } 14585 } 14586 ast_mutex_unlock(&p_old->lock); 14587 } 14588 ast_mutex_unlock(&iflock); 14589 } 14590 if (!p->expiry) 14591 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14592 } 14593 return 1; 14594 }
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 12210 of file chan_sip.c.
References __sip_ack(), __sip_semi_ack(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_set_flag, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), do_proxy_auth(), FALSE, find_sdp(), find_sip_method(), sip_pvt::flags, get_header(), gettag(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), hangup_sip2cause(), ast_channel::hangupcause, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, sip_pvt::method, NONE, option_debug, option_verbose, sip_pvt::owner, parse_moved_contact(), process_sdp(), sip_pvt::refer, sip_pvt::relatedpeer, SIP_ACK, sip_alreadygone(), SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_OUTGOING, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_REFER, SIP_REGISTER, sipdebug, stop_media_flows(), sip_pvt::subscribed, text, transmit_request(), VERBOSE_PREFIX_3, and XMIT_UNRELIABLE.
12211 { 12212 struct ast_channel *owner; 12213 int sipmethod; 12214 int res = 1; 12215 const char *c = get_header(req, "Cseq"); 12216 const char *msg = strchr(c, ' '); 12217 12218 if (!msg) 12219 msg = ""; 12220 else 12221 msg++; 12222 sipmethod = find_sip_method(msg); 12223 12224 owner = p->owner; 12225 if (owner) 12226 owner->hangupcause = hangup_sip2cause(resp); 12227 12228 /* Acknowledge whatever it is destined for */ 12229 if ((resp >= 100) && (resp <= 199)) 12230 __sip_semi_ack(p, seqno, 0, sipmethod); 12231 else 12232 __sip_ack(p, seqno, 0, sipmethod); 12233 12234 /* Get their tag if we haven't already */ 12235 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 12236 char tag[128]; 12237 12238 gettag(req, "To", tag, sizeof(tag)); 12239 ast_string_field_set(p, theirtag, tag); 12240 } 12241 if (p->relatedpeer && p->method == SIP_OPTIONS) { 12242 /* We don't really care what the response is, just that it replied back. 12243 Well, as long as it's not a 100 response... since we might 12244 need to hang around for something more "definitive" */ 12245 if (resp != 100) 12246 handle_response_peerpoke(p, resp, req); 12247 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12248 switch(resp) { 12249 case 100: /* 100 Trying */ 12250 case 101: /* 101 Dialog establishment */ 12251 if (sipmethod == SIP_INVITE) 12252 handle_response_invite(p, resp, rest, req, seqno); 12253 break; 12254 case 183: /* 183 Session Progress */ 12255 if (sipmethod == SIP_INVITE) 12256 handle_response_invite(p, resp, rest, req, seqno); 12257 break; 12258 case 180: /* 180 Ringing */ 12259 if (sipmethod == SIP_INVITE) 12260 handle_response_invite(p, resp, rest, req, seqno); 12261 break; 12262 case 200: /* 200 OK */ 12263 p->authtries = 0; /* Reset authentication counter */ 12264 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 12265 /* We successfully transmitted a message 12266 or a video update request in INFO */ 12267 /* Nothing happens here - the message is inside a dialog */ 12268 } else if (sipmethod == SIP_INVITE) { 12269 handle_response_invite(p, resp, rest, req, seqno); 12270 } else if (sipmethod == SIP_NOTIFY) { 12271 /* They got the notify, this is the end */ 12272 if (p->owner) { 12273 if (!p->refer) { 12274 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 12275 ast_queue_hangup(p->owner); 12276 } else if (option_debug > 3) 12277 ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n"); 12278 } else { 12279 if (p->subscribed == NONE) 12280 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12281 } 12282 } else if (sipmethod == SIP_REGISTER) 12283 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12284 else if (sipmethod == SIP_BYE) /* Ok, we're ready to go */ 12285 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12286 break; 12287 case 202: /* Transfer accepted */ 12288 if (sipmethod == SIP_REFER) 12289 handle_response_refer(p, resp, rest, req, seqno); 12290 break; 12291 case 401: /* Not www-authorized on SIP method */ 12292 if (sipmethod == SIP_INVITE) 12293 handle_response_invite(p, resp, rest, req, seqno); 12294 else if (sipmethod == SIP_REFER) 12295 handle_response_refer(p, resp, rest, req, seqno); 12296 else if (p->registry && sipmethod == SIP_REGISTER) 12297 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12298 else { 12299 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 12300 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12301 } 12302 break; 12303 case 403: /* Forbidden - we failed authentication */ 12304 if (sipmethod == SIP_INVITE) 12305 handle_response_invite(p, resp, rest, req, seqno); 12306 else if (p->registry && sipmethod == SIP_REGISTER) 12307 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12308 else { 12309 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 12310 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12311 } 12312 break; 12313 case 404: /* Not found */ 12314 if (p->registry && sipmethod == SIP_REGISTER) 12315 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12316 else if (sipmethod == SIP_INVITE) 12317 handle_response_invite(p, resp, rest, req, seqno); 12318 else if (owner) 12319 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12320 break; 12321 case 407: /* Proxy auth required */ 12322 if (sipmethod == SIP_INVITE) 12323 handle_response_invite(p, resp, rest, req, seqno); 12324 else if (sipmethod == SIP_REFER) 12325 handle_response_refer(p, resp, rest, req, seqno); 12326 else if (p->registry && sipmethod == SIP_REGISTER) 12327 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12328 else if (sipmethod == SIP_BYE) { 12329 if (ast_strlen_zero(p->authname)) 12330 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 12331 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12332 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12333 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 12334 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12335 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12336 } 12337 } else /* We can't handle this, giving up in a bad way */ 12338 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12339 12340 break; 12341 case 481: /* Call leg does not exist */ 12342 if (sipmethod == SIP_INVITE) { 12343 handle_response_invite(p, resp, rest, req, seqno); 12344 } else if (sipmethod == SIP_REFER) { 12345 handle_response_refer(p, resp, rest, req, seqno); 12346 } else if (sipmethod == SIP_BYE) { 12347 /* The other side has no transaction to bye, 12348 just assume it's all right then */ 12349 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12350 } else if (sipmethod == SIP_CANCEL) { 12351 /* The other side has no transaction to cancel, 12352 just assume it's all right then */ 12353 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12354 } else { 12355 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12356 /* Guessing that this is not an important request */ 12357 } 12358 break; 12359 case 487: 12360 if (sipmethod == SIP_INVITE) 12361 handle_response_invite(p, resp, rest, req, seqno); 12362 break; 12363 case 488: /* Not acceptable here - codec error */ 12364 if (sipmethod == SIP_INVITE) 12365 handle_response_invite(p, resp, rest, req, seqno); 12366 break; 12367 case 491: /* Pending */ 12368 if (sipmethod == SIP_INVITE) 12369 handle_response_invite(p, resp, rest, req, seqno); 12370 else { 12371 if (option_debug) 12372 ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 12373 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12374 } 12375 break; 12376 case 501: /* Not Implemented */ 12377 if (sipmethod == SIP_INVITE) 12378 handle_response_invite(p, resp, rest, req, seqno); 12379 else if (sipmethod == SIP_REFER) 12380 handle_response_refer(p, resp, rest, req, seqno); 12381 else 12382 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg); 12383 break; 12384 case 603: /* Declined transfer */ 12385 if (sipmethod == SIP_REFER) { 12386 handle_response_refer(p, resp, rest, req, seqno); 12387 break; 12388 } 12389 /* Fallthrough */ 12390 default: 12391 if ((resp >= 300) && (resp < 700)) { 12392 /* Fatal response */ 12393 if ((option_verbose > 2) && (resp != 487)) 12394 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 12395 12396 if (sipmethod == SIP_INVITE) 12397 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12398 12399 /* XXX Locking issues?? XXX */ 12400 switch(resp) { 12401 case 300: /* Multiple Choices */ 12402 case 301: /* Moved permenantly */ 12403 case 302: /* Moved temporarily */ 12404 case 305: /* Use Proxy */ 12405 parse_moved_contact(p, req); 12406 /* Fall through */ 12407 case 486: /* Busy here */ 12408 case 600: /* Busy everywhere */ 12409 case 603: /* Decline */ 12410 if (p->owner) 12411 ast_queue_control(p->owner, AST_CONTROL_BUSY); 12412 break; 12413 case 482: /* 12414 \note SIP is incapable of performing a hairpin call, which 12415 is yet another failure of not having a layer 2 (again, YAY 12416 IETF for thinking ahead). So we treat this as a call 12417 forward and hope we end up at the right place... */ 12418 if (option_debug) 12419 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 12420 if (p->owner) 12421 ast_string_field_build(p->owner, call_forward, 12422 "Local/%s@%s", p->username, p->context); 12423 /* Fall through */ 12424 case 480: /* Temporarily Unavailable */ 12425 case 404: /* Not Found */ 12426 case 410: /* Gone */ 12427 case 400: /* Bad Request */ 12428 case 500: /* Server error */ 12429 if (sipmethod == SIP_REFER) { 12430 handle_response_refer(p, resp, rest, req, seqno); 12431 break; 12432 } 12433 /* Fall through */ 12434 case 503: /* Service Unavailable */ 12435 case 504: /* Server Timeout */ 12436 if (owner) 12437 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12438 break; 12439 default: 12440 /* Send hangup */ 12441 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 12442 ast_queue_hangup(p->owner); 12443 break; 12444 } 12445 /* ACK on invite */ 12446 if (sipmethod == SIP_INVITE) 12447 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12448 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 12449 sip_alreadygone(p); 12450 if (!p->owner) 12451 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12452 } else if ((resp >= 100) && (resp < 200)) { 12453 if (sipmethod == SIP_INVITE) { 12454 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12455 sip_cancel_destroy(p); 12456 if (find_sdp(req)) 12457 process_sdp(p, req); 12458 if (p->owner) { 12459 /* Queue a progress frame */ 12460 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12461 } 12462 } 12463 } else 12464 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)); 12465 } 12466 } else { 12467 /* Responses to OUTGOING SIP requests on INCOMING calls 12468 get handled here. As well as out-of-call message responses */ 12469 if (ast_test_flag(req, SIP_PKT_DEBUG)) 12470 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 12471 12472 if (sipmethod == SIP_INVITE && resp == 200) { 12473 /* Tags in early session is replaced by the tag in 200 OK, which is 12474 the final reply to our INVITE */ 12475 char tag[128]; 12476 12477 gettag(req, "To", tag, sizeof(tag)); 12478 ast_string_field_set(p, theirtag, tag); 12479 } 12480 12481 switch(resp) { 12482 case 200: 12483 if (sipmethod == SIP_INVITE) { 12484 handle_response_invite(p, resp, rest, req, seqno); 12485 } else if (sipmethod == SIP_CANCEL) { 12486 if (option_debug) 12487 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 12488 12489 /* Wait for 487, then destroy */ 12490 } else if (sipmethod == SIP_NOTIFY) { 12491 /* They got the notify, this is the end */ 12492 if (p->owner) { 12493 if (p->refer) { 12494 if (option_debug) 12495 ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n"); 12496 } else 12497 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 12498 /* ast_queue_hangup(p->owner); Disabled */ 12499 } else { 12500 if (!p->subscribed && !p->refer) 12501 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12502 } 12503 } else if (sipmethod == SIP_BYE) 12504 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12505 else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) 12506 /* We successfully transmitted a message or 12507 a video update request in INFO */ 12508 ; 12509 else if (sipmethod == SIP_BYE) 12510 /* Ok, we're ready to go */ 12511 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12512 break; 12513 case 202: /* Transfer accepted */ 12514 if (sipmethod == SIP_REFER) 12515 handle_response_refer(p, resp, rest, req, seqno); 12516 break; 12517 case 401: /* www-auth */ 12518 case 407: 12519 if (sipmethod == SIP_REFER) 12520 handle_response_refer(p, resp, rest, req, seqno); 12521 else if (sipmethod == SIP_INVITE) 12522 handle_response_invite(p, resp, rest, req, seqno); 12523 else if (sipmethod == SIP_BYE) { 12524 char *auth, *auth2; 12525 12526 auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate"); 12527 auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization"); 12528 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 12529 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12530 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12531 } 12532 } 12533 break; 12534 case 481: /* Call leg does not exist */ 12535 if (sipmethod == SIP_INVITE) { 12536 /* Re-invite failed */ 12537 handle_response_invite(p, resp, rest, req, seqno); 12538 } else if (sipmethod == SIP_BYE) { 12539 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12540 } else if (sipdebug) { 12541 ast_log (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 12542 } 12543 break; 12544 case 501: /* Not Implemented */ 12545 if (sipmethod == SIP_INVITE) 12546 handle_response_invite(p, resp, rest, req, seqno); 12547 else if (sipmethod == SIP_REFER) 12548 handle_response_refer(p, resp, rest, req, seqno); 12549 break; 12550 case 603: /* Declined transfer */ 12551 if (sipmethod == SIP_REFER) { 12552 handle_response_refer(p, resp, rest, req, seqno); 12553 break; 12554 } 12555 /* Fallthrough */ 12556 default: /* Errors without handlers */ 12557 if ((resp >= 100) && (resp < 200)) { 12558 if (sipmethod == SIP_INVITE) { /* re-invite */ 12559 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12560 sip_cancel_destroy(p); 12561 } 12562 } 12563 if ((resp >= 300) && (resp < 700)) { 12564 if ((option_verbose > 2) && (resp != 487)) 12565 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)); 12566 switch(resp) { 12567 case 488: /* Not acceptable here - codec error */ 12568 case 603: /* Decline */ 12569 case 500: /* Server error */ 12570 case 503: /* Service Unavailable */ 12571 case 504: /* Server timeout */ 12572 12573 if (sipmethod == SIP_INVITE) { /* re-invite failed */ 12574 sip_cancel_destroy(p); 12575 } 12576 break; 12577 } 12578 } 12579 break; 12580 } 12581 } 12582 }
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 11668 of file chan_sip.c.
References ast_channel::_state, ast_bridged_channel(), AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, ast_queue_control(), ast_queue_frame(), ast_queue_hangup(), ast_rtp_set_rtptimers_onhold(), ast_sched_del(), ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_string_field_free, ast_test_flag, authenticate(), build_route(), check_pendings(), DEC_CALL_LIMIT, DEC_CALL_RINGING, DEFAULT_TRANS_TIMEOUT, do_proxy_auth(), FALSE, find_sdp(), sip_pvt::flags, get_header(), sip_pvt::initid, INV_CALLING, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, option_debug, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, sched, set_address_from_contact(), SIP_ACK, sip_alreadygone(), SIP_ALREADYGONE, sip_cancel_destroy(), sip_handle_t38_reinvite(), SIP_INVITE, SIP_NEEDDESTROY, SIP_OUTGOING, SIP_PENDINGBYE, SIP_PKT_IGNORE, sip_scheddestroy(), sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, T38_PEER_REINVITE, ast_channel::tech, ast_channel::tech_pvt, transmit_request(), TRUE, ast_channel_tech::type, sip_pvt::udptl, update_call_counter(), WWW_AUTH, and XMIT_UNRELIABLE.
Referenced by handle_response().
11669 { 11670 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 11671 int res = 0; 11672 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 11673 struct ast_channel *bridgepeer = NULL; 11674 11675 if (option_debug > 3) { 11676 if (reinvite) 11677 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 11678 else 11679 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 11680 } 11681 11682 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */ 11683 if (option_debug) 11684 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 11685 return; 11686 } 11687 11688 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 11689 if (p->initid > -1) { 11690 /* Don't auto congest anymore since we've gotten something useful back */ 11691 ast_sched_del(sched, p->initid); 11692 p->initid = -1; 11693 } 11694 11695 /* RFC3261 says we must treat every 1xx response (but not 100) 11696 that we don't recognize as if it was 183. 11697 */ 11698 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 183) 11699 resp = 183; 11700 11701 /* Any response between 100 and 199 is PROCEEDING */ 11702 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 11703 p->invitestate = INV_PROCEEDING; 11704 11705 /* Final response, not 200 ? */ 11706 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 11707 p->invitestate = INV_COMPLETED; 11708 11709 11710 switch (resp) { 11711 case 100: /* Trying */ 11712 case 101: /* Dialog establishment */ 11713 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11714 sip_cancel_destroy(p); 11715 check_pendings(p); 11716 break; 11717 11718 case 180: /* 180 Ringing */ 11719 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11720 sip_cancel_destroy(p); 11721 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 11722 ast_queue_control(p->owner, AST_CONTROL_RINGING); 11723 if (p->owner->_state != AST_STATE_UP) { 11724 ast_setstate(p->owner, AST_STATE_RINGING); 11725 } 11726 } 11727 if (find_sdp(req)) { 11728 p->invitestate = INV_EARLY_MEDIA; 11729 res = process_sdp(p, req); 11730 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 11731 /* Queue a progress frame only if we have SDP in 180 */ 11732 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 11733 } 11734 } 11735 check_pendings(p); 11736 break; 11737 11738 case 183: /* Session progress */ 11739 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11740 sip_cancel_destroy(p); 11741 /* Ignore 183 Session progress without SDP */ 11742 if (find_sdp(req)) { 11743 p->invitestate = INV_EARLY_MEDIA; 11744 res = process_sdp(p, req); 11745 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 11746 /* Queue a progress frame */ 11747 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 11748 } 11749 } 11750 check_pendings(p); 11751 break; 11752 11753 case 200: /* 200 OK on invite - someone's answering our call */ 11754 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11755 sip_cancel_destroy(p); 11756 p->authtries = 0; 11757 if (find_sdp(req)) { 11758 if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) 11759 if (!reinvite) 11760 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 11761 /* For re-invites, we try to recover */ 11762 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 11763 } 11764 11765 /* Parse contact header for continued conversation */ 11766 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 11767 /* This is important when we have a SIP proxy between us and the phone */ 11768 if (outgoing) { 11769 update_call_counter(p, DEC_CALL_RINGING); 11770 parse_ok_contact(p, req); 11771 if(set_address_from_contact(p)) { 11772 /* Bad contact - we don't know how to reach this device */ 11773 /* We need to ACK, but then send a bye */ 11774 /* OEJ: Possible issue that may need a check: 11775 If we have a proxy route between us and the device, 11776 should we care about resolving the contact 11777 or should we just send it? 11778 */ 11779 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11780 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 11781 } 11782 11783 /* Save Record-Route for any later requests we make on this dialogue */ 11784 build_route(p, req, 1); 11785 } 11786 11787 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 11788 struct sip_pvt *bridgepvt = NULL; 11789 11790 if (!bridgepeer->tech) { 11791 ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n"); 11792 break; 11793 } 11794 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 11795 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 11796 if (bridgepvt->udptl) { 11797 if (p->t38.state == T38_PEER_REINVITE) { 11798 sip_handle_t38_reinvite(bridgepeer, p, 0); 11799 ast_rtp_set_rtptimers_onhold(p->rtp); 11800 if (p->vrtp) 11801 ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */ 11802 } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) { 11803 ast_log(LOG_WARNING, "RTP re-inivte after T38 session not handled yet !\n"); 11804 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 11805 /* XXXX Should we really destroy this session here, without any response at all??? */ 11806 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11807 } 11808 } else { 11809 if (option_debug > 1) 11810 ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n"); 11811 ast_mutex_lock(&bridgepvt->lock); 11812 bridgepvt->t38.state = T38_DISABLED; 11813 ast_mutex_unlock(&bridgepvt->lock); 11814 if (option_debug) 11815 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type); 11816 p->t38.state = T38_DISABLED; 11817 if (option_debug > 1) 11818 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 11819 } 11820 } else { 11821 /* Other side is not a SIP channel */ 11822 if (option_debug > 1) 11823 ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n"); 11824 p->t38.state = T38_DISABLED; 11825 if (option_debug > 1) 11826 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 11827 } 11828 } 11829 if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) { 11830 /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */ 11831 p->t38.state = T38_ENABLED; 11832 if (option_debug) 11833 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 11834 } 11835 11836 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 11837 if (!reinvite) { 11838 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 11839 } else { /* RE-invite */ 11840 ast_queue_frame(p->owner, &ast_null_frame); 11841 } 11842 } else { 11843 /* It's possible we're getting an 200 OK after we've tried to disconnect 11844 by sending CANCEL */ 11845 /* First send ACK, then send bye */ 11846 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11847 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 11848 } 11849 /* If I understand this right, the branch is different for a non-200 ACK only */ 11850 p->invitestate = INV_TERMINATED; 11851 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 11852 check_pendings(p); 11853 break; 11854 case 407: /* Proxy authentication */ 11855 case 401: /* Www auth */ 11856 /* First we ACK */ 11857 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 11858 if (p->options) 11859 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 11860 11861 /* Then we AUTH */ 11862 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 11863 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 11864 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 11865 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 11866 if (p->authtries < MAX_AUTHTRIES) 11867 p->invitestate = INV_CALLING; 11868 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 11869 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 11870 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 11871 sip_alreadygone(p); 11872 if (p->owner) 11873 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 11874 } 11875 } 11876 break; 11877 11878 case 403: /* Forbidden */ 11879 /* First we ACK */ 11880 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 11881 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 11882 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) 11883 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 11884 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 11885 sip_alreadygone(p); 11886 break; 11887 11888 case 404: /* Not found */ 11889 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 11890 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 11891 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 11892 sip_alreadygone(p); 11893 break; 11894 11895 case 481: /* Call leg does not exist */ 11896 /* Could be REFER caused INVITE with replaces */ 11897 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 11898 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 11899 if (p->owner) 11900 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 11901 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11902 break; 11903 case 487: /* Cancelled transaction */ 11904 /* We have sent CANCEL on an outbound INVITE 11905 This transaction is already scheduled to be killed by sip_hangup(). 11906 */ 11907 transmit_request(p, SIP_ACK, seqno, 0, 0); 11908 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 11909 ast_queue_hangup(p->owner); 11910 else if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11911 update_call_counter(p, DEC_CALL_LIMIT); 11912 break; 11913 case 488: /* Not acceptable here */ 11914 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 11915 if (reinvite && p->udptl) { 11916 /* If this is a T.38 call, we should go back to 11917 audio. If this is an audio call - something went 11918 terribly wrong since we don't renegotiate codecs, 11919 only IP/port . 11920 */ 11921 p->t38.state = T38_DISABLED; 11922 /* Try to reset RTP timers */ 11923 ast_rtp_set_rtptimers_onhold(p->rtp); 11924 ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n"); 11925 11926 /*! \bug Is there any way we can go back to the audio call on both 11927 sides here? 11928 */ 11929 /* While figuring that out, hangup the call */ 11930 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 11931 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 11932 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 11933 } else { 11934 /* We can't set up this call, so give up */ 11935 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 11936 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 11937 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 11938 } 11939 break; 11940 case 491: /* Pending */ 11941 /* we really should have to wait a while, then retransmit */ 11942 /* We should support the retry-after at some point */ 11943 /* At this point, we treat this as a congestion */ 11944 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 11945 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 11946 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 11947 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 11948 break; 11949 11950 case 501: /* Not implemented */ 11951 transmit_request(p, SIP_ACK, seqno, 0, 0); 11952 if (p->owner) 11953 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 11954 break; 11955 } 11956 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 12150 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, sip_peer::call, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, EVENT_FLAG_SYSTEM, sip_pvt::flags, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::maxms, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::relatedpeer, s, sched, SIP_NEEDDESTROY, and sip_poke_peer_s().
Referenced by handle_response().
12151 { 12152 struct sip_peer *peer = p->relatedpeer; 12153 int statechanged, is_reachable, was_reachable; 12154 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 12155 12156 /* 12157 * Compute the response time to a ping (goes in peer->lastms.) 12158 * -1 means did not respond, 0 means unknown, 12159 * 1..maxms is a valid response, >maxms means late response. 12160 */ 12161 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 12162 pingtime = 1; 12163 12164 /* Now determine new state and whether it has changed. 12165 * Use some helper variables to simplify the writing 12166 * of the expressions. 12167 */ 12168 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 12169 is_reachable = pingtime <= peer->maxms; 12170 statechanged = peer->lastms == 0 /* yes, unknown before */ 12171 || was_reachable != is_reachable; 12172 12173 peer->lastms = pingtime; 12174 peer->call = NULL; 12175 if (statechanged) { 12176 const char *s = is_reachable ? "Reachable" : "Lagged"; 12177 12178 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 12179 peer->name, s, pingtime, peer->maxms); 12180 ast_device_state_changed("SIP/%s", peer->name); 12181 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 12182 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 12183 peer->name, s, pingtime); 12184 } 12185 12186 if (peer->pokeexpire > -1) 12187 ast_sched_del(sched, peer->pokeexpire); 12188 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12189 12190 /* Try again eventually */ 12191 peer->pokeexpire = ast_sched_add(sched, 12192 is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, 12193 sip_poke_peer_s, peer); 12194 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 11961 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().
11962 { 11963 char *auth = "Proxy-Authenticate"; 11964 char *auth2 = "Proxy-Authorization"; 11965 11966 /* If no refer structure exists, then do nothing */ 11967 if (!p->refer) 11968 return; 11969 11970 switch (resp) { 11971 case 202: /* Transfer accepted */ 11972 /* We need to do something here */ 11973 /* The transferee is now sending INVITE to target */ 11974 p->refer->status = REFER_ACCEPTED; 11975 /* Now wait for next message */ 11976 if (option_debug > 2) 11977 ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n"); 11978 /* We should hang along, waiting for NOTIFY's here */ 11979 break; 11980 11981 case 401: /* Not www-authorized on SIP method */ 11982 case 407: /* Proxy auth */ 11983 if (ast_strlen_zero(p->authname)) { 11984 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 11985 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 11986 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 11987 } 11988 if (resp == 401) { 11989 auth = "WWW-Authenticate"; 11990 auth2 = "Authorization"; 11991 } 11992 if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) { 11993 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 11994 p->refer->status = REFER_NOAUTH; 11995 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 11996 } 11997 break; 11998 case 481: /* Call leg does not exist */ 11999 12000 /* A transfer with Replaces did not work */ 12001 /* OEJ: We should Set flag, cancel the REFER, go back 12002 to original call - but right now we can't */ 12003 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 12004 if (p->owner) 12005 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12006 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12007 break; 12008 12009 case 500: /* Server error */ 12010 case 501: /* Method not implemented */ 12011 /* Return to the current call onhold */ 12012 /* Status flag needed to be reset */ 12013 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 12014 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12015 p->refer->status = REFER_FAILED; 12016 break; 12017 case 603: /* Transfer declined */ 12018 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 12019 p->refer->status = REFER_FAILED; 12020 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12021 break; 12022 } 12023 }
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 12026 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, sched, SIP_NEEDDESTROY, sip_registry_destroy(), sip_reregister(), sip_scheddestroy(), sipdebug, strcasestr(), and sip_registry::timeout.
Referenced by handle_response().
12027 { 12028 int expires, expires_ms; 12029 struct sip_registry *r; 12030 r=p->registry; 12031 12032 switch (resp) { 12033 case 401: /* Unauthorized */ 12034 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 12035 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 12036 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12037 } 12038 break; 12039 case 403: /* Forbidden */ 12040 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 12041 if (global_regattempts_max) 12042 p->registry->regattempts = global_regattempts_max+1; 12043 ast_sched_del(sched, r->timeout); 12044 r->timeout = -1; 12045 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12046 break; 12047 case 404: /* Not found */ 12048 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 12049 if (global_regattempts_max) 12050 p->registry->regattempts = global_regattempts_max+1; 12051 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12052 r->call = NULL; 12053 ast_sched_del(sched, r->timeout); 12054 r->timeout = -1; 12055 break; 12056 case 407: /* Proxy auth */ 12057 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 12058 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 12059 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12060 } 12061 break; 12062 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 12063 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 12064 if (global_regattempts_max) 12065 p->registry->regattempts = global_regattempts_max+1; 12066 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12067 r->call = NULL; 12068 ast_sched_del(sched, r->timeout); 12069 r->timeout = -1; 12070 break; 12071 case 200: /* 200 OK */ 12072 if (!r) { 12073 ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n"); 12074 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12075 return 0; 12076 } 12077 12078 r->regstate = REG_STATE_REGISTERED; 12079 r->regtime = time(NULL); /* Reset time of last succesful registration */ 12080 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 12081 r->regattempts = 0; 12082 if (option_debug) 12083 ast_log(LOG_DEBUG, "Registration successful\n"); 12084 if (r->timeout > -1) { 12085 if (option_debug) 12086 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 12087 ast_sched_del(sched, r->timeout); 12088 } 12089 r->timeout=-1; 12090 r->call = NULL; 12091 p->registry = NULL; 12092 /* Let this one hang around until we have all the responses */ 12093 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12094 /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */ 12095 12096 /* set us up for re-registering */ 12097 /* figure out how long we got registered for */ 12098 if (r->expire > -1) 12099 ast_sched_del(sched, r->expire); 12100 /* according to section 6.13 of RFC, contact headers override 12101 expires headers, so check those first */ 12102 expires = 0; 12103 12104 /* XXX todo: try to save the extra call */ 12105 if (!ast_strlen_zero(get_header(req, "Contact"))) { 12106 const char *contact = NULL; 12107 const char *tmptmp = NULL; 12108 int start = 0; 12109 for(;;) { 12110 contact = __get_header(req, "Contact", &start); 12111 /* this loop ensures we get a contact header about our register request */ 12112 if(!ast_strlen_zero(contact)) { 12113 if( (tmptmp=strstr(contact, p->our_contact))) { 12114 contact=tmptmp; 12115 break; 12116 } 12117 } else 12118 break; 12119 } 12120 tmptmp = strcasestr(contact, "expires="); 12121 if (tmptmp) { 12122 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 12123 expires = 0; 12124 } 12125 12126 } 12127 if (!expires) 12128 expires=atoi(get_header(req, "expires")); 12129 if (!expires) 12130 expires=default_expiry; 12131 12132 expires_ms = expires * 1000; 12133 if (expires <= EXPIRY_GUARD_LIMIT) 12134 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 12135 else 12136 expires_ms -= EXPIRY_GUARD_SECS * 1000; 12137 if (sipdebug) 12138 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 12139 12140 r->refresh= (int) expires_ms / 1000; 12141 12142 /* Schedule re-registration before we expire */ 12143 r->expire=ast_sched_add(sched, expires_ms, sip_reregister, r); 12144 ASTOBJ_UNREF(r, sip_registry_destroy); 12145 } 12146 return 1; 12147 }
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 3229 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().
03230 { 03231 switch (cause) { 03232 case AST_CAUSE_UNALLOCATED: /* 1 */ 03233 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 03234 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 03235 return "404 Not Found"; 03236 case AST_CAUSE_CONGESTION: /* 34 */ 03237 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 03238 return "503 Service Unavailable"; 03239 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 03240 return "408 Request Timeout"; 03241 case AST_CAUSE_NO_ANSWER: /* 19 */ 03242 return "480 Temporarily unavailable"; 03243 case AST_CAUSE_CALL_REJECTED: /* 21 */ 03244 return "403 Forbidden"; 03245 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 03246 return "410 Gone"; 03247 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 03248 return "480 Temporarily unavailable"; 03249 case AST_CAUSE_INVALID_NUMBER_FORMAT: 03250 return "484 Address incomplete"; 03251 case AST_CAUSE_USER_BUSY: 03252 return "486 Busy here"; 03253 case AST_CAUSE_FAILURE: 03254 return "500 Server internal failure"; 03255 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 03256 return "501 Not Implemented"; 03257 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 03258 return "503 Service Unavailable"; 03259 /* Used in chan_iax2 */ 03260 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 03261 return "502 Bad Gateway"; 03262 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 03263 return "488 Not Acceptable Here"; 03264 03265 case AST_CAUSE_NOTDEFINED: 03266 default: 03267 if (option_debug) 03268 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 03269 return NULL; 03270 } 03271 03272 /* Never reached */ 03273 return 0; 03274 }
static int hangup_sip2cause | ( | int | cause | ) | [static] |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 3117 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().
03118 { 03119 /* Possible values taken from causes.h */ 03120 03121 switch(cause) { 03122 case 401: /* Unauthorized */ 03123 return AST_CAUSE_CALL_REJECTED; 03124 case 403: /* Not found */ 03125 return AST_CAUSE_CALL_REJECTED; 03126 case 404: /* Not found */ 03127 return AST_CAUSE_UNALLOCATED; 03128 case 405: /* Method not allowed */ 03129 return AST_CAUSE_INTERWORKING; 03130 case 407: /* Proxy authentication required */ 03131 return AST_CAUSE_CALL_REJECTED; 03132 case 408: /* No reaction */ 03133 return AST_CAUSE_NO_USER_RESPONSE; 03134 case 409: /* Conflict */ 03135 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 03136 case 410: /* Gone */ 03137 return AST_CAUSE_UNALLOCATED; 03138 case 411: /* Length required */ 03139 return AST_CAUSE_INTERWORKING; 03140 case 413: /* Request entity too large */ 03141 return AST_CAUSE_INTERWORKING; 03142 case 414: /* Request URI too large */ 03143 return AST_CAUSE_INTERWORKING; 03144 case 415: /* Unsupported media type */ 03145 return AST_CAUSE_INTERWORKING; 03146 case 420: /* Bad extension */ 03147 return AST_CAUSE_NO_ROUTE_DESTINATION; 03148 case 480: /* No answer */ 03149 return AST_CAUSE_NO_ANSWER; 03150 case 481: /* No answer */ 03151 return AST_CAUSE_INTERWORKING; 03152 case 482: /* Loop detected */ 03153 return AST_CAUSE_INTERWORKING; 03154 case 483: /* Too many hops */ 03155 return AST_CAUSE_NO_ANSWER; 03156 case 484: /* Address incomplete */ 03157 return AST_CAUSE_INVALID_NUMBER_FORMAT; 03158 case 485: /* Ambigous */ 03159 return AST_CAUSE_UNALLOCATED; 03160 case 486: /* Busy everywhere */ 03161 return AST_CAUSE_BUSY; 03162 case 487: /* Request terminated */ 03163 return AST_CAUSE_INTERWORKING; 03164 case 488: /* No codecs approved */ 03165 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03166 case 491: /* Request pending */ 03167 return AST_CAUSE_INTERWORKING; 03168 case 493: /* Undecipherable */ 03169 return AST_CAUSE_INTERWORKING; 03170 case 500: /* Server internal failure */ 03171 return AST_CAUSE_FAILURE; 03172 case 501: /* Call rejected */ 03173 return AST_CAUSE_FACILITY_REJECTED; 03174 case 502: 03175 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03176 case 503: /* Service unavailable */ 03177 return AST_CAUSE_CONGESTION; 03178 case 504: /* Gateway timeout */ 03179 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 03180 case 505: /* SIP version not supported */ 03181 return AST_CAUSE_INTERWORKING; 03182 case 600: /* Busy everywhere */ 03183 return AST_CAUSE_USER_BUSY; 03184 case 603: /* Decline */ 03185 return AST_CAUSE_CALL_REJECTED; 03186 case 604: /* Does not exist anywhere */ 03187 return AST_CAUSE_UNALLOCATED; 03188 case 606: /* Not acceptable */ 03189 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03190 default: 03191 return AST_CAUSE_NORMAL; 03192 } 03193 /* Never reached */ 03194 return 0; 03195 }
static int init_req | ( | struct sip_request * | req, | |
int | sipmethod, | |||
const char * | recip | |||
) | [static] |
Initialize SIP request.
Definition at line 5572 of file chan_sip.c.
References sip_methods, and cfsip_methods::text.
05573 { 05574 /* Initialize a request */ 05575 memset(req, 0, sizeof(*req)); 05576 req->method = sipmethod; 05577 req->header[0] = req->data; 05578 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 05579 req->len = strlen(req->header[0]); 05580 req->headers++; 05581 return 0; 05582 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 5559 of file chan_sip.c.
References SIP_RESPONSE.
05560 { 05561 /* Initialize a response */ 05562 memset(resp, 0, sizeof(*resp)); 05563 resp->method = SIP_RESPONSE; 05564 resp->header[0] = resp->data; 05565 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 05566 resp->len = strlen(resp->header[0]); 05567 resp->headers++; 05568 return 0; 05569 }
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 1620 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().
01621 { 01622 if (p->initreq.headers && option_debug) { 01623 ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 01624 } 01625 /* Use this as the basis */ 01626 copy_request(&p->initreq, req); 01627 parse_request(&p->initreq); 01628 if (ast_test_flag(req, SIP_PKT_DEBUG)) 01629 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 01630 }
static void initreqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod | |||
) | [static] |
Initiate new SIP request to peer/user.
Definition at line 6648 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().
06649 { 06650 char invite_buf[256] = ""; 06651 char *invite = invite_buf; 06652 size_t invite_max = sizeof(invite_buf); 06653 char from[256]; 06654 char to[256]; 06655 char tmp[BUFSIZ/2]; 06656 char tmp2[BUFSIZ/2]; 06657 const char *l = NULL, *n = NULL; 06658 const char *urioptions = ""; 06659 06660 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 06661 const char *s = p->username; /* being a string field, cannot be NULL */ 06662 06663 /* Test p->username against allowed characters in AST_DIGIT_ANY 06664 If it matches the allowed characters list, then sipuser = ";user=phone" 06665 If not, then sipuser = "" 06666 */ 06667 /* + is allowed in first position in a tel: uri */ 06668 if (*s == '+') 06669 s++; 06670 for (; *s; s++) { 06671 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 06672 break; 06673 } 06674 /* If we have only digits, add ;user=phone to the uri */ 06675 if (*s) 06676 urioptions = ";user=phone"; 06677 } 06678 06679 06680 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 06681 06682 if (p->owner) { 06683 l = p->owner->cid.cid_num; 06684 n = p->owner->cid.cid_name; 06685 } 06686 /* if we are not sending RPID and user wants his callerid restricted */ 06687 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 06688 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 06689 l = CALLERID_UNKNOWN; 06690 n = l; 06691 } 06692 if (ast_strlen_zero(l)) 06693 l = default_callerid; 06694 if (ast_strlen_zero(n)) 06695 n = l; 06696 /* Allow user to be overridden */ 06697 if (!ast_strlen_zero(p->fromuser)) 06698 l = p->fromuser; 06699 else /* Save for any further attempts */ 06700 ast_string_field_set(p, fromuser, l); 06701 06702 /* Allow user to be overridden */ 06703 if (!ast_strlen_zero(p->fromname)) 06704 n = p->fromname; 06705 else /* Save for any further attempts */ 06706 ast_string_field_set(p, fromname, n); 06707 06708 if (pedanticsipchecking) { 06709 ast_uri_encode(n, tmp, sizeof(tmp), 0); 06710 n = tmp; 06711 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 06712 l = tmp2; 06713 } 06714 06715 if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain)) 06716 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); 06717 else 06718 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag); 06719 06720 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 06721 if (!ast_strlen_zero(p->fullcontact)) { 06722 /* If we have full contact, trust it */ 06723 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 06724 } else { 06725 /* Otherwise, use the username while waiting for registration */ 06726 ast_build_string(&invite, &invite_max, "sip:"); 06727 if (!ast_strlen_zero(p->username)) { 06728 n = p->username; 06729 if (pedanticsipchecking) { 06730 ast_uri_encode(n, tmp, sizeof(tmp), 0); 06731 n = tmp; 06732 } 06733 ast_build_string(&invite, &invite_max, "%s@", n); 06734 } 06735 ast_build_string(&invite, &invite_max, "%s", p->tohost); 06736 if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT) 06737 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 06738 ast_build_string(&invite, &invite_max, "%s", urioptions); 06739 } 06740 06741 /* If custom URI options have been provided, append them */ 06742 if (p->options && p->options->uri_options) 06743 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 06744 06745 ast_string_field_set(p, uri, invite_buf); 06746 06747 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 06748 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 06749 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", p->uri, p->theirtag); 06750 } else if (p->options && p->options->vxml_url) { 06751 /* If there is a VXML URL append it to the SIP URL */ 06752 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 06753 } else 06754 snprintf(to, sizeof(to), "<%s>", p->uri); 06755 06756 init_req(req, sipmethod, p->uri); 06757 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 06758 06759 add_header(req, "Via", p->via); 06760 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 06761 * OTOH, then we won't have anything in p->route anyway */ 06762 /* Build Remote Party-ID and From */ 06763 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 06764 build_rpid(p); 06765 add_header(req, "From", p->rpid_from); 06766 } else 06767 add_header(req, "From", from); 06768 add_header(req, "To", to); 06769 ast_string_field_set(p, exten, l); 06770 build_contact(p); 06771 add_header(req, "Contact", p->our_contact); 06772 add_header(req, "Call-ID", p->callid); 06773 add_header(req, "CSeq", tmp); 06774 if (!ast_strlen_zero(global_useragent)) 06775 add_header(req, "User-Agent", global_useragent); 06776 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 06777 if (!ast_strlen_zero(p->rpid)) 06778 add_header(req, "Remote-Party-ID", p->rpid); 06779 }
static const char * insecure2str | ( | int | port, | |
int | invite | |||
) | const [static] |
Convert Insecure setting to printable string.
Definition at line 9729 of file chan_sip.c.
Referenced by _sip_show_peer().
09730 { 09731 if (port && invite) 09732 return "port,invite"; 09733 else if (port) 09734 return "port"; 09735 else if (invite) 09736 return "invite"; 09737 else 09738 return "no"; 09739 }
static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 7927 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
07928 { 07929 if (!route) 07930 ast_verbose("list_route: no route\n"); 07931 else { 07932 for (;route; route = route->next) 07933 ast_verbose("list_route: hop: <%s>\n", route->hop); 07934 } 07935 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 17409 of file chan_sip.c.
References ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register(), ast_log(), ast_manager_register2(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_application(), ast_rtp_proto_register(), ast_udptl_proto_register(), ASTOBJ_CONTAINER_INIT, CHANNEL_MODULE_LOAD, checksipdomain_function, cli_sip, EVENT_FLAG_SYSTEM, io, io_context_create(), io_context_destroy(), LOG_ERROR, manager_sip_show_peer(), manager_sip_show_peers(), peerl, regl, reload_config(), restart_monitor(), sched, sched_context_create(), sched_context_destroy(), sip_addheader(), sip_dtmfmode(), sip_header_function, sip_poke_all_peers(), sip_rtp, sip_send_all_registers(), sip_tech, sip_udptl, sipchaninfo_function, sippeer_function, and userl.
17410 { 17411 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 17412 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 17413 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 17414 17415 if (!(sched = sched_context_create())) { 17416 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 17417 return AST_MODULE_LOAD_FAILURE; 17418 } 17419 17420 if (!(io = io_context_create())) { 17421 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 17422 sched_context_destroy(sched); 17423 return AST_MODULE_LOAD_FAILURE; 17424 } 17425 17426 sip_reloadreason = CHANNEL_MODULE_LOAD; 17427 17428 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 17429 return AST_MODULE_LOAD_DECLINE; 17430 17431 /* Make sure we can register our sip channel type */ 17432 if (ast_channel_register(&sip_tech)) { 17433 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 17434 io_context_destroy(io); 17435 sched_context_destroy(sched); 17436 return AST_MODULE_LOAD_FAILURE; 17437 } 17438 17439 /* Register all CLI functions for SIP */ 17440 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 17441 17442 /* Tell the RTP subdriver that we're here */ 17443 ast_rtp_proto_register(&sip_rtp); 17444 17445 /* Tell the UDPTL subdriver that we're here */ 17446 ast_udptl_proto_register(&sip_udptl); 17447 17448 /* Register dialplan applications */ 17449 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 17450 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 17451 17452 /* Register dialplan functions */ 17453 ast_custom_function_register(&sip_header_function); 17454 ast_custom_function_register(&sippeer_function); 17455 ast_custom_function_register(&sipchaninfo_function); 17456 ast_custom_function_register(&checksipdomain_function); 17457 17458 /* Register manager commands */ 17459 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 17460 "List SIP peers (text format)", mandescr_show_peers); 17461 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 17462 "Show SIP peer (text format)", mandescr_show_peer); 17463 17464 sip_poke_all_peers(); 17465 sip_send_all_registers(); 17466 17467 /* And start the monitor for the first time */ 17468 restart_monitor(); 17469 17470 return AST_MODULE_LOAD_SUCCESS; 17471 }
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 13698 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().
13699 { 13700 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 13701 /* Chan 2: Call from Asterisk to target */ 13702 int res = 0; 13703 struct sip_pvt *targetcall_pvt; 13704 13705 /* Check if the call ID of the replaces header does exist locally */ 13706 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 13707 transferer->refer->replaces_callid_fromtag))) { 13708 if (transferer->refer->localtransfer) { 13709 /* We did not find the refered call. Sorry, can't accept then */ 13710 transmit_response(transferer, "202 Accepted", req); 13711 /* Let's fake a response from someone else in order 13712 to follow the standard */ 13713 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 13714 append_history(transferer, "Xfer", "Refer failed"); 13715 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 13716 transferer->refer->status = REFER_FAILED; 13717 return -1; 13718 } 13719 /* Fall through for remote transfers that we did not find locally */ 13720 if (option_debug > 2) 13721 ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 13722 return 0; 13723 } 13724 13725 /* Ok, we can accept this transfer */ 13726 transmit_response(transferer, "202 Accepted", req); 13727 append_history(transferer, "Xfer", "Refer accepted"); 13728 if (!targetcall_pvt->owner) { /* No active channel */ 13729 if (option_debug > 3) 13730 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n"); 13731 /* Cancel transfer */ 13732 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 13733 append_history(transferer, "Xfer", "Refer failed"); 13734 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 13735 transferer->refer->status = REFER_FAILED; 13736 ast_mutex_unlock(&targetcall_pvt->lock); 13737 ast_channel_unlock(current->chan1); 13738 return -1; 13739 } 13740 13741 /* We have a channel, find the bridge */ 13742 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 13743 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 13744 13745 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 13746 /* Wrong state of new channel */ 13747 if (option_debug > 3) { 13748 if (target.chan2) 13749 ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 13750 else if (target.chan1->_state != AST_STATE_RING) 13751 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n"); 13752 else 13753 ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n"); 13754 } 13755 } 13756 13757 /* Transfer */ 13758 if (option_debug > 3 && sipdebug) { 13759 if (current->chan2) /* We have two bridges */ 13760 ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 13761 else /* One bridge, propably transfer of IVR/voicemail etc */ 13762 ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 13763 } 13764 13765 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 13766 13767 /* Perform the transfer */ 13768 res = attempt_transfer(current, &target); 13769 ast_mutex_unlock(&targetcall_pvt->lock); 13770 if (res) { 13771 /* Failed transfer */ 13772 /* Could find better message, but they will get the point */ 13773 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy", TRUE); 13774 append_history(transferer, "Xfer", "Refer failed"); 13775 if (targetcall_pvt->owner) 13776 ast_channel_unlock(targetcall_pvt->owner); 13777 /* Right now, we have to hangup, sorry. Bridge is destroyed */ 13778 ast_hangup(transferer->owner); 13779 } else { 13780 /* Transfer succeeded! */ 13781 13782 /* Tell transferer that we're done. */ 13783 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 13784 append_history(transferer, "Xfer", "Refer succeeded"); 13785 transferer->refer->status = REFER_200OK; 13786 if (targetcall_pvt->owner) { 13787 if (option_debug) 13788 ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 13789 ast_channel_unlock(targetcall_pvt->owner); 13790 } 13791 } 13792 return 1; 13793 }
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 4525 of file chan_sip.c.
References t.
Referenced by sipsock_read().
04526 { 04527 int h = 0, t = 0; 04528 int lws = 0; 04529 04530 for (; h < len;) { 04531 /* Eliminate all CRs */ 04532 if (msgbuf[h] == '\r') { 04533 h++; 04534 continue; 04535 } 04536 /* Check for end-of-line */ 04537 if (msgbuf[h] == '\n') { 04538 /* Check for end-of-message */ 04539 if (h + 1 == len) 04540 break; 04541 /* Check for a continuation line */ 04542 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 04543 /* Merge continuation line */ 04544 h++; 04545 continue; 04546 } 04547 /* Propagate LF and start new line */ 04548 msgbuf[t++] = msgbuf[h++]; 04549 lws = 0; 04550 continue; 04551 } 04552 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 04553 if (lws) { 04554 h++; 04555 continue; 04556 } 04557 msgbuf[t++] = msgbuf[h++]; 04558 lws = 1; 04559 continue; 04560 } 04561 msgbuf[t++] = msgbuf[h++]; 04562 if (lws) 04563 lws = 0; 04564 } 04565 msgbuf[t] = '\0'; 04566 return t; 04567 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Make our SIP dialog tag.
Definition at line 4197 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().
04198 { 04199 snprintf(tagbuf, len, "as%08lx", ast_random()); 04200 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 9974 of file chan_sip.c.
References _sip_show_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), and s.
Referenced by load_module().
09975 { 09976 const char *a[4]; 09977 const char *peer; 09978 int ret; 09979 09980 peer = astman_get_header(m,"Peer"); 09981 if (ast_strlen_zero(peer)) { 09982 astman_send_error(s, m, "Peer: <name> missing.\n"); 09983 return 0; 09984 } 09985 a[0] = "sip"; 09986 a[1] = "show"; 09987 a[2] = "peer"; 09988 a[3] = peer; 09989 09990 ret = _sip_show_peer(1, -1, s, m, 4, a); 09991 astman_append(s, "\r\n\r\n" ); 09992 return ret; 09993 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 9525 of file chan_sip.c.
References _sip_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), s, and total.
Referenced by load_module().
09526 { 09527 const char *id = astman_get_header(m,"ActionID"); 09528 const char *a[] = {"sip", "show", "peers"}; 09529 char idtext[256] = ""; 09530 int total = 0; 09531 09532 if (!ast_strlen_zero(id)) 09533 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 09534 09535 astman_send_ack(s, m, "Peer status list will follow"); 09536 /* List the peers in separate manager events */ 09537 _sip_show_peers(-1, &total, s, m, 3, a); 09538 /* Send final confirmation */ 09539 astman_append(s, 09540 "Event: PeerlistComplete\r\n" 09541 "ListItems: %d\r\n" 09542 "%s" 09543 "\r\n", total, idtext); 09544 return 0; 09545 }
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 1646 of file chan_sip.c.
References len, sip_methods, and text.
Referenced by __sip_semi_ack(), and find_sip_method().
01647 { 01648 int len = strlen(sip_methods[id].text); 01649 int l_name = name ? strlen(name) : 0; 01650 /* true if the string is long enough, and ends with whitespace, and matches */ 01651 return (l_name >= len && name[len] < 33 && 01652 !strncasecmp(sip_methods[id].text, name, len)); 01653 }
static char * nat2str | ( | int | nat | ) | const [static] |
Convert NAT setting to text string.
Definition at line 9428 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().
09429 { 09430 switch(nat) { 09431 case SIP_NAT_NEVER: 09432 return "No"; 09433 case SIP_NAT_ROUTE: 09434 return "Route"; 09435 case SIP_NAT_ALWAYS: 09436 return "Always"; 09437 case SIP_NAT_RFC3581: 09438 return "RFC3581"; 09439 default: 09440 return "Unknown"; 09441 } 09442 }
static void parse_copy | ( | struct sip_request * | dst, | |
const struct sip_request * | src | |||
) | [static] |
Copy SIP request, parse it.
Definition at line 2139 of file chan_sip.c.
References sip_request::data, sip_request::len, and parse_request().
Referenced by send_request(), and send_response().
02140 { 02141 memset(dst, 0, sizeof(*dst)); 02142 memcpy(dst->data, src->data, sizeof(dst->data)); 02143 dst->len = src->len; 02144 parse_request(dst); 02145 }
static void parse_moved_contact | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Parse 302 Moved temporalily response.
Definition at line 11603 of file chan_sip.c.
References ast_log(), 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 strsep().
Referenced by handle_response().
11604 { 11605 char tmp[BUFSIZ]; 11606 char *s, *e; 11607 char *domain; 11608 11609 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 11610 s = get_in_brackets(tmp); 11611 s = strsep(&s, ";"); /* strip ; and beyond */ 11612 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 11613 if (!strncasecmp(s, "sip:", 4)) 11614 s += 4; 11615 e = strchr(s, '/'); 11616 if (e) 11617 *e = '\0'; 11618 if (option_debug) 11619 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 11620 if (p->owner) 11621 ast_string_field_build(p->owner, call_forward, "SIP/%s", s); 11622 } else { 11623 e = strchr(tmp, '@'); 11624 if (e) { 11625 *e++ = '\0'; 11626 domain = e; 11627 } else { 11628 /* No username part */ 11629 domain = tmp; 11630 } 11631 e = strchr(tmp, '/'); 11632 if (e) 11633 *e = '\0'; 11634 if (!strncasecmp(s, "sip:", 4)) 11635 s += 4; 11636 if (option_debug > 1) 11637 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 11638 if (p->owner) { 11639 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 11640 ast_string_field_set(p->owner, call_forward, s); 11641 } 11642 } 11643 }
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 7682 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().
07683 { 07684 char contact[BUFSIZ]; 07685 char *c; 07686 07687 /* Look for brackets */ 07688 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 07689 c = get_in_brackets(contact); 07690 07691 /* Save full contact to call pvt for later bye or re-invite */ 07692 ast_string_field_set(pvt, fullcontact, c); 07693 07694 /* Save URI for later ACKs, BYE or RE-invites */ 07695 ast_string_field_set(pvt, okcontacturi, c); 07696 07697 /* We should return false for URI:s we can't handle, 07698 like sips:, tel:, mailto:,ldap: etc */ 07699 return TRUE; 07700 }
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 7765 of file chan_sip.c.
References sip_peer::addr, ahp, ast_db_put(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_sched_when(), ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose(), destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, expire_register(), sip_pvt::expiry, sip_peer::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), hp, inaddrcmp(), sip_peer::lastms, LOG_NOTICE, LOG_WARNING, manager_event(), option_verbose, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_pvt::recv, register_peer_exten(), sched, SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), SIP_REALTIME, sip_pvt::sipoptions, sip_peer::sipoptions, STANDARD_SIP_PORT, strcasestr(), strsep(), sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3.
Referenced by register_verify().
07766 { 07767 char contact[BUFSIZ]; 07768 char data[BUFSIZ]; 07769 const char *expires = get_header(req, "Expires"); 07770 int expiry = atoi(expires); 07771 char *curi, *n, *pt; 07772 int port; 07773 const char *useragent; 07774 struct hostent *hp; 07775 struct ast_hostent ahp; 07776 struct sockaddr_in oldsin; 07777 07778 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 07779 07780 if (ast_strlen_zero(expires)) { /* No expires header */ 07781 expires = strcasestr(contact, ";expires="); 07782 if (expires) { 07783 /* XXX bug here, we overwrite the string */ 07784 expires = strsep((char **) &expires, ";"); /* trim ; and beyond */ 07785 if (sscanf(expires + 9, "%d", &expiry) != 1) 07786 expiry = default_expiry; 07787 } else { 07788 /* Nothing has been specified */ 07789 expiry = default_expiry; 07790 } 07791 } 07792 07793 /* Look for brackets */ 07794 curi = contact; 07795 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 07796 strsep(&curi, ";"); /* This is Header options, not URI options */ 07797 curi = get_in_brackets(contact); 07798 07799 /* if they did not specify Contact: or Expires:, they are querying 07800 what we currently have stored as their contact address, so return 07801 it 07802 */ 07803 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 07804 /* If we have an active registration, tell them when the registration is going to expire */ 07805 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 07806 pvt->expiry = ast_sched_when(sched, peer->expire); 07807 return PARSE_REGISTER_QUERY; 07808 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 07809 /* This means remove all registrations and return OK */ 07810 memset(&peer->addr, 0, sizeof(peer->addr)); 07811 if (peer->expire > -1) 07812 ast_sched_del(sched, peer->expire); 07813 peer->expire = -1; 07814 07815 destroy_association(peer); 07816 07817 register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */ 07818 peer->fullcontact[0] = '\0'; 07819 peer->useragent[0] = '\0'; 07820 peer->sipoptions = 0; 07821 peer->lastms = 0; 07822 07823 if (option_verbose > 2) 07824 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name); 07825 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name); 07826 return PARSE_REGISTER_UPDATE; 07827 } 07828 07829 /* Store whatever we got as a contact from the client */ 07830 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 07831 07832 /* For the 200 OK, we should use the received contact */ 07833 ast_string_field_build(pvt, our_contact, "<%s>", curi); 07834 07835 /* Make sure it's a SIP URL */ 07836 if (strncasecmp(curi, "sip:", 4)) { 07837 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 07838 } else 07839 curi += 4; 07840 /* Ditch q */ 07841 curi = strsep(&curi, ";"); 07842 /* Grab host */ 07843 n = strchr(curi, '@'); 07844 if (!n) { 07845 n = curi; 07846 curi = NULL; 07847 } else 07848 *n++ = '\0'; 07849 pt = strchr(n, ':'); 07850 if (pt) { 07851 *pt++ = '\0'; 07852 port = atoi(pt); 07853 } else 07854 port = STANDARD_SIP_PORT; 07855 oldsin = peer->addr; 07856 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 07857 /* XXX This could block for a long time XXX */ 07858 hp = ast_gethostbyname(n, &ahp); 07859 if (!hp) { 07860 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 07861 return PARSE_REGISTER_FAILED; 07862 } 07863 peer->addr.sin_family = AF_INET; 07864 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 07865 peer->addr.sin_port = htons(port); 07866 } else { 07867 /* Don't trust the contact field. Just use what they came to us 07868 with */ 07869 peer->addr = pvt->recv; 07870 } 07871 07872 /* Save SIP options profile */ 07873 peer->sipoptions = pvt->sipoptions; 07874 07875 if (curi) /* Overwrite the default username from config at registration */ 07876 ast_copy_string(peer->username, curi, sizeof(peer->username)); 07877 else 07878 peer->username[0] = '\0'; 07879 07880 if (peer->expire > -1) { 07881 ast_sched_del(sched, peer->expire); 07882 peer->expire = -1; 07883 } 07884 if (expiry > max_expiry) 07885 expiry = max_expiry; 07886 if (expiry < min_expiry) 07887 expiry = min_expiry; 07888 peer->expire = ast_test_flag(&peer->flags[0], SIP_REALTIME) ? -1 : 07889 ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 07890 pvt->expiry = expiry; 07891 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); 07892 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07893 ast_db_put("SIP/Registry", peer->name, data); 07894 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 07895 07896 /* Is this a new IP address for us? */ 07897 if (inaddrcmp(&peer->addr, &oldsin)) { 07898 sip_poke_peer(peer); 07899 if (option_verbose > 2) 07900 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); 07901 register_peer_exten(peer, 1); 07902 } 07903 07904 /* Save User agent */ 07905 useragent = get_header(req, "User-Agent"); 07906 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 07907 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 07908 if (option_verbose > 3) 07909 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 07910 } 07911 return PARSE_REGISTER_UPDATE; 07912 }
static void parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 4572 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().
04573 { 04574 /* Divide fields by NULL's */ 04575 char *c; 04576 int f = 0; 04577 04578 c = req->data; 04579 04580 /* First header starts immediately */ 04581 req->header[f] = c; 04582 while(*c) { 04583 if (*c == '\n') { 04584 /* We've got a new header */ 04585 *c = 0; 04586 04587 if (sipdebug && option_debug > 3) 04588 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04589 if (ast_strlen_zero(req->header[f])) { 04590 /* Line by itself means we're now in content */ 04591 c++; 04592 break; 04593 } 04594 if (f >= SIP_MAX_HEADERS - 1) { 04595 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 04596 } else 04597 f++; 04598 req->header[f] = c + 1; 04599 } else if (*c == '\r') { 04600 /* Ignore but eliminate \r's */ 04601 *c = 0; 04602 } 04603 c++; 04604 } 04605 /* Check for last header */ 04606 if (!ast_strlen_zero(req->header[f])) { 04607 if (sipdebug && option_debug > 3) 04608 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04609 f++; 04610 } 04611 req->headers = f; 04612 /* Now we process any mime content */ 04613 f = 0; 04614 req->line[f] = c; 04615 while(*c) { 04616 if (*c == '\n') { 04617 /* We've got a new line */ 04618 *c = 0; 04619 if (sipdebug && option_debug > 3) 04620 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 04621 if (f >= SIP_MAX_LINES - 1) { 04622 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 04623 } else 04624 f++; 04625 req->line[f] = c + 1; 04626 } else if (*c == '\r') { 04627 /* Ignore and eliminate \r's */ 04628 *c = 0; 04629 } 04630 c++; 04631 } 04632 /* Check for last line */ 04633 if (!ast_strlen_zero(req->line[f])) 04634 f++; 04635 req->lines = f; 04636 if (*c) 04637 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 04638 /* Split up the first line parts */ 04639 determine_firstline_parts(req); 04640 }
static unsigned int parse_sip_options | ( | struct sip_pvt * | pvt, | |
const char * | supported | |||
) | [static] |
Parse supported header in incoming packet.
Definition at line 1670 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), FALSE, LOG_DEBUG, ast_udptl_protocol::next, option_debug, sip_options, sipdebug, sip_pvt::sipoptions, text, and TRUE.
Referenced by handle_request_invite().
01671 { 01672 char *next, *sep; 01673 char *temp; 01674 unsigned int profile = 0; 01675 int i, found; 01676 01677 if (ast_strlen_zero(supported) ) 01678 return 0; 01679 temp = ast_strdupa(supported); 01680 01681 if (option_debug > 2 && sipdebug) 01682 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01683 01684 for (next = temp; next; next = sep) { 01685 found = FALSE; 01686 if ( (sep = strchr(next, ',')) != NULL) 01687 *sep++ = '\0'; 01688 next = ast_skip_blanks(next); 01689 if (option_debug > 2 && sipdebug) 01690 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01691 for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) { 01692 if (!strcasecmp(next, sip_options[i].text)) { 01693 profile |= sip_options[i].id; 01694 found = TRUE; 01695 if (option_debug > 2 && sipdebug) 01696 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01697 break; 01698 } 01699 } 01700 if (!found && option_debug > 2 && sipdebug) { 01701 if (!strncasecmp(next, "x-", 2)) 01702 ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next); 01703 else 01704 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01705 } 01706 } 01707 01708 if (pvt) 01709 pvt->sipoptions = profile; 01710 return profile; 01711 }
static int peer_status | ( | struct sip_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
Report Peer status in character string.
Definition at line 9447 of file chan_sip.c.
References sip_peer::lastms, and sip_peer::maxms.
09448 { 09449 int res = 0; 09450 if (peer->maxms) { 09451 if (peer->lastms < 0) { 09452 ast_copy_string(status, "UNREACHABLE", statuslen); 09453 } else if (peer->lastms > peer->maxms) { 09454 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 09455 res = 1; 09456 } else if (peer->lastms) { 09457 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 09458 res = 1; 09459 } else { 09460 ast_copy_string(status, "UNKNOWN", statuslen); 09461 } 09462 } else { 09463 ast_copy_string(status, "Unmonitored", statuslen); 09464 /* Checking if port is 0 */ 09465 res = -1; 09466 } 09467 return res; 09468 }
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 9915 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().
09916 { 09917 int x, codec; 09918 09919 for(x = 0; x < 32 ; x++) { 09920 codec = ast_codec_pref_index(pref, x); 09921 if (!codec) 09922 break; 09923 ast_cli(fd, "%s", ast_getformatname(codec)); 09924 ast_cli(fd, ":%d", pref->framing[x]); 09925 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 09926 ast_cli(fd, ","); 09927 } 09928 if (!x) 09929 ast_cli(fd, "none"); 09930 }
static void print_group | ( | int | fd, | |
ast_group_t | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 9706 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
09707 { 09708 char buf[256]; 09709 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 09710 }
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 4721 of file chan_sip.c.
References append_history, 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, sip_request::data, debug, EVENT_FLAG_CALL, 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, manager_event(), 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_CALL_ONHOLD_ACTIVE, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, SIP_PAGE2_RFC2833_COMPENSATE, sip_peer_hold(), 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.
04722 { 04723 const char *m; /* SDP media offer */ 04724 const char *c; 04725 const char *a; 04726 char host[258]; 04727 int len = -1; 04728 int portno = -1; /*!< RTP Audio port number */ 04729 int vportno = -1; /*!< RTP Video port number */ 04730 int udptlportno = -1; 04731 int peert38capability = 0; 04732 char s[256]; 04733 int old = 0; 04734 04735 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 04736 int peercapability = 0, peernoncodeccapability = 0; 04737 int vpeercapability = 0, vpeernoncodeccapability = 0; 04738 struct sockaddr_in sin; /*!< media socket address */ 04739 struct sockaddr_in vsin; /*!< Video socket address */ 04740 04741 const char *codecs; 04742 struct hostent *hp; /*!< RTP Audio host IP */ 04743 struct hostent *vhp = NULL; /*!< RTP video host IP */ 04744 struct ast_hostent audiohp; 04745 struct ast_hostent videohp; 04746 int codec; 04747 int destiterator = 0; 04748 int iterator; 04749 int sendonly = -1; 04750 int numberofports; 04751 struct ast_rtp *newaudiortp, *newvideortp; /* Buffers for codec handling */ 04752 int newjointcapability; /* Negotiated capability */ 04753 int newpeercapability; 04754 int newnoncodeccapability; 04755 int numberofmediastreams = 0; 04756 int debug = sip_debug_test_pvt(p); 04757 04758 int found_rtpmap_codecs[32]; 04759 int last_rtpmap_codec=0; 04760 04761 if (!p->rtp) { 04762 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 04763 return -1; 04764 } 04765 04766 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 04767 newaudiortp = alloca(ast_rtp_alloc_size()); 04768 memset(newaudiortp, 0, ast_rtp_alloc_size()); 04769 ast_rtp_new_init(newaudiortp); 04770 ast_rtp_pt_clear(newaudiortp); 04771 04772 newvideortp = alloca(ast_rtp_alloc_size()); 04773 memset(newvideortp, 0, ast_rtp_alloc_size()); 04774 ast_rtp_new_init(newvideortp); 04775 ast_rtp_pt_clear(newvideortp); 04776 04777 /* Update our last rtprx when we receive an SDP, too */ 04778 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 04779 04780 04781 /* Try to find first media stream */ 04782 m = get_sdp(req, "m"); 04783 destiterator = req->sdp_start; 04784 c = get_sdp_iterate(&destiterator, req, "c"); 04785 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 04786 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 04787 return -1; 04788 } 04789 04790 /* Check for IPv4 address (not IPv6 yet) */ 04791 if (sscanf(c, "IN IP4 %256s", host) != 1) { 04792 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 04793 return -1; 04794 } 04795 04796 /* XXX This could block for a long time, and block the main thread! XXX */ 04797 hp = ast_gethostbyname(host, &audiohp); 04798 if (!hp) { 04799 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 04800 return -1; 04801 } 04802 vhp = hp; /* Copy to video address as default too */ 04803 04804 iterator = req->sdp_start; 04805 ast_set_flag(&p->flags[0], SIP_NOVIDEO); 04806 04807 04808 /* Find media streams in this SDP offer */ 04809 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 04810 int x; 04811 int audio = FALSE; 04812 04813 numberofports = 1; 04814 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 04815 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) { 04816 audio = TRUE; 04817 numberofmediastreams++; 04818 /* Found audio stream in this media definition */ 04819 portno = x; 04820 /* Scan through the RTP payload types specified in a "m=" line: */ 04821 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 04822 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 04823 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 04824 return -1; 04825 } 04826 if (debug) 04827 ast_verbose("Found RTP audio format %d\n", codec); 04828 ast_rtp_set_m_type(newaudiortp, codec); 04829 } 04830 } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 04831 (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) { 04832 /* If it is not audio - is it video ? */ 04833 ast_clear_flag(&p->flags[0], SIP_NOVIDEO); 04834 numberofmediastreams++; 04835 vportno = x; 04836 /* Scan through the RTP payload types specified in a "m=" line: */ 04837 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 04838 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 04839 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 04840 return -1; 04841 } 04842 if (debug) 04843 ast_verbose("Found RTP video format %d\n", codec); 04844 ast_rtp_set_m_type(newvideortp, codec); 04845 } 04846 } else if (p->udptl && ( (sscanf(m, "image %d udptl t38%n", &x, &len) == 1) || 04847 (sscanf(m, "image %d UDPTL t38%n", &x, &len) == 1) )) { 04848 if (debug) 04849 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 04850 udptlportno = x; 04851 numberofmediastreams++; 04852 04853 if (p->owner && p->lastinvite) { 04854 p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ 04855 if (option_debug > 1) 04856 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); 04857 } else { 04858 p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ 04859 if (option_debug > 1) 04860 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 04861 } 04862 } else 04863 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 04864 if (numberofports > 1) 04865 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 04866 04867 04868 /* Check for Media-description-level-address for audio */ 04869 c = get_sdp_iterate(&destiterator, req, "c"); 04870 if (!ast_strlen_zero(c)) { 04871 if (sscanf(c, "IN IP4 %256s", host) != 1) { 04872 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 04873 } else { 04874 /* XXX This could block for a long time, and block the main thread! XXX */ 04875 if (audio) { 04876 if ( !(hp = ast_gethostbyname(host, &audiohp))) { 04877 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c); 04878 return -2; 04879 } 04880 } else if (!(vhp = ast_gethostbyname(host, &videohp))) { 04881 ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c); 04882 return -2; 04883 } 04884 } 04885 04886 } 04887 } 04888 if (portno == -1 && vportno == -1 && udptlportno == -1) 04889 /* No acceptable offer found in SDP - we have no ports */ 04890 /* Do not change RTP or VRTP if this is a re-invite */ 04891 return -2; 04892 04893 if (numberofmediastreams > 2) 04894 /* We have too many fax, audio and/or video media streams, fail this offer */ 04895 return -3; 04896 04897 /* RTP addresses and ports for audio and video */ 04898 sin.sin_family = AF_INET; 04899 vsin.sin_family = AF_INET; 04900 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 04901 if (vhp) 04902 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 04903 04904 /* Setup UDPTL port number */ 04905 if (p->udptl) { 04906 if (udptlportno > 0) { 04907 sin.sin_port = htons(udptlportno); 04908 ast_udptl_set_peer(p->udptl, &sin); 04909 if (debug) 04910 ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 04911 } else { 04912 ast_udptl_stop(p->udptl); 04913 if (debug) 04914 ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n"); 04915 } 04916 } 04917 04918 04919 if (p->rtp) { 04920 if (portno > 0) { 04921 sin.sin_port = htons(portno); 04922 ast_rtp_set_peer(p->rtp, &sin); 04923 if (debug) 04924 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 04925 } else { 04926 if (udptlportno > 0) { 04927 if (debug) 04928 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session. Callid %s\n", p->callid); 04929 } else { 04930 ast_rtp_stop(p->rtp); 04931 if (debug) 04932 ast_verbose("Peer doesn't provide audio. Callid %s\n", p->callid); 04933 } 04934 } 04935 } 04936 /* Setup video port number */ 04937 if (vportno != -1) 04938 vsin.sin_port = htons(vportno); 04939 04940 /* Next, scan through each "a=rtpmap:" line, noting each 04941 * specified RTP payload type (with corresponding MIME subtype): 04942 */ 04943 /* XXX This needs to be done per media stream, since it's media stream specific */ 04944 iterator = req->sdp_start; 04945 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 04946 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 04947 if (option_debug > 1) { 04948 int breakout = FALSE; 04949 04950 /* If we're debugging, check for unsupported sdp options */ 04951 if (!strncasecmp(a, "rtcp:", (size_t) 5)) { 04952 if (debug) 04953 ast_verbose("Got unsupported a:rtcp in SDP offer \n"); 04954 breakout = TRUE; 04955 } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) { 04956 /* Format parameters: Not supported */ 04957 /* Note: This is used for codec parameters, like bitrate for 04958 G722 and video formats for H263 and H264 04959 See RFC2327 for an example */ 04960 if (debug) 04961 ast_verbose("Got unsupported a:fmtp in SDP offer \n"); 04962 breakout = TRUE; 04963 } else if (!strncasecmp(a, "framerate:", (size_t) 10)) { 04964 /* Video stuff: Not supported */ 04965 if (debug) 04966 ast_verbose("Got unsupported a:framerate in SDP offer \n"); 04967 breakout = TRUE; 04968 } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) { 04969 /* Video stuff: Not supported */ 04970 if (debug) 04971 ast_verbose("Got unsupported a:maxprate in SDP offer \n"); 04972 breakout = TRUE; 04973 } else if (!strncasecmp(a, "crypto:", (size_t) 7)) { 04974 /* SRTP stuff, not yet supported */ 04975 if (debug) 04976 ast_verbose("Got unsupported a:crypto in SDP offer \n"); 04977 breakout = TRUE; 04978 } 04979 if (breakout) /* We have a match, skip to next header */ 04980 continue; 04981 } 04982 if (!strcasecmp(a, "sendonly")) { 04983 if (sendonly == -1) 04984 sendonly = 1; 04985 continue; 04986 } else if (!strcasecmp(a, "inactive")) { 04987 if (sendonly == -1) 04988 sendonly = 2; 04989 continue; 04990 } else if (!strcasecmp(a, "sendrecv")) { 04991 if (sendonly == -1) 04992 sendonly = 0; 04993 continue; 04994 } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 04995 char *tmp = strrchr(a, ':'); 04996 long int framing = 0; 04997 if (tmp) { 04998 tmp++; 04999 framing = strtol(tmp, NULL, 10); 05000 if (framing == LONG_MIN || framing == LONG_MAX) { 05001 framing = 0; 05002 if (option_debug) 05003 ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a); 05004 } 05005 } 05006 if (framing && last_rtpmap_codec) { 05007 if (p->autoframing) { 05008 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 05009 int codec_n; 05010 int format = 0; 05011 for (codec_n = 0; codec_n < last_rtpmap_codec; codec_n++) { 05012 format = ast_rtp_codec_getformat(found_rtpmap_codecs[codec_n]); 05013 if (!format) /* non-codec or not found */ 05014 continue; 05015 if (option_debug) 05016 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 05017 ast_codec_pref_setsize(pref, format, framing); 05018 } 05019 ast_rtp_codec_setpref(p->rtp, pref); 05020 } 05021 } 05022 memset(&found_rtpmap_codecs, 0, sizeof(found_rtpmap_codecs)); 05023 last_rtpmap_codec = 0; 05024 continue; 05025 } else if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) == 2) { 05026 /* We have a rtpmap to handle */ 05027 if (debug) 05028 ast_verbose("Found description format %s for ID %d\n", mimeSubtype, codec); 05029 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05030 last_rtpmap_codec++; 05031 05032 /* Note: should really look at the 'freq' and '#chans' params too */ 05033 ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 05034 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0); 05035 if (p->vrtp) 05036 ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0); 05037 } 05038 } 05039 05040 if (udptlportno != -1) { 05041 int found = 0, x; 05042 05043 old = 0; 05044 05045 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 05046 iterator = req->sdp_start; 05047 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05048 if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) { 05049 found = 1; 05050 if (option_debug > 2) 05051 ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x); 05052 } else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1)) { 05053 found = 1; 05054 if (option_debug > 2) 05055 ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x); 05056 switch (x) { 05057 case 14400: 05058 peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05059 break; 05060 case 12000: 05061 peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05062 break; 05063 case 9600: 05064 peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05065 break; 05066 case 7200: 05067 peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05068 break; 05069 case 4800: 05070 peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 05071 break; 05072 case 2400: 05073 peert38capability |= T38FAX_RATE_2400; 05074 break; 05075 } 05076 } else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) { 05077 found = 1; 05078 if (option_debug > 2) 05079 ast_log(LOG_DEBUG, "FaxVersion: %d\n",x); 05080 if (x == 0) 05081 peert38capability |= T38FAX_VERSION_0; 05082 else if (x == 1) 05083 peert38capability |= T38FAX_VERSION_1; 05084 } else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1)) { 05085 found = 1; 05086 if (option_debug > 2) 05087 ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x); 05088 ast_udptl_set_far_max_datagram(p->udptl, x); 05089 ast_udptl_set_local_max_datagram(p->udptl, x); 05090 } else if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) { 05091 found = 1; 05092 if (option_debug > 2) 05093 ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x); 05094 if (x == 1) 05095 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05096 } else if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) { 05097 found = 1; 05098 if (option_debug > 2) 05099 ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x); 05100 if (x == 1) 05101 peert38capability |= T38FAX_TRANSCODING_MMR; 05102 } 05103 if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) { 05104 found = 1; 05105 if (option_debug > 2) 05106 ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x); 05107 if (x == 1) 05108 peert38capability |= T38FAX_TRANSCODING_JBIG; 05109 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 05110 found = 1; 05111 if (option_debug > 2) 05112 ast_log(LOG_DEBUG, "RateManagement: %s\n", s); 05113 if (!strcasecmp(s, "localTCF")) 05114 peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 05115 else if (!strcasecmp(s, "transferredTCF")) 05116 peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 05117 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 05118 found = 1; 05119 if (option_debug > 2) 05120 ast_log(LOG_DEBUG, "UDP EC: %s\n", s); 05121 if (!strcasecmp(s, "t38UDPRedundancy")) { 05122 peert38capability |= T38FAX_UDP_EC_REDUNDANCY; 05123 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 05124 } else if (!strcasecmp(s, "t38UDPFEC")) { 05125 peert38capability |= T38FAX_UDP_EC_FEC; 05126 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 05127 } else { 05128 peert38capability |= T38FAX_UDP_EC_NONE; 05129 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05130 } 05131 } 05132 } 05133 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 05134 p->t38.peercapability = peert38capability; 05135 p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */ 05136 peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 05137 p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */ 05138 } 05139 if (debug) 05140 ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 05141 p->t38.capability, 05142 p->t38.peercapability, 05143 p->t38.jointcapability); 05144 } else { 05145 p->t38.state = T38_DISABLED; 05146 if (option_debug > 2) 05147 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05148 } 05149 05150 /* Now gather all of the codecs that we are asked for: */ 05151 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 05152 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 05153 05154 newjointcapability = p->capability & (peercapability | vpeercapability); 05155 newpeercapability = (peercapability | vpeercapability); 05156 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 05157 05158 05159 if (debug) { 05160 /* shame on whoever coded this.... */ 05161 char s1[BUFSIZ], s2[BUFSIZ], s3[BUFSIZ], s4[BUFSIZ]; 05162 05163 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 05164 ast_getformatname_multiple(s1, BUFSIZ, p->capability), 05165 ast_getformatname_multiple(s2, BUFSIZ, newpeercapability), 05166 ast_getformatname_multiple(s3, BUFSIZ, vpeercapability), 05167 ast_getformatname_multiple(s4, BUFSIZ, newjointcapability)); 05168 05169 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 05170 ast_rtp_lookup_mime_multiple(s1, BUFSIZ, p->noncodeccapability, 0, 0), 05171 ast_rtp_lookup_mime_multiple(s2, BUFSIZ, peernoncodeccapability, 0, 0), 05172 ast_rtp_lookup_mime_multiple(s3, BUFSIZ, newnoncodeccapability, 0, 0)); 05173 } 05174 if (!newjointcapability) { 05175 /* If T.38 was not negotiated either, totally bail out... */ 05176 if (!p->t38.jointcapability) { 05177 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 05178 /* Do NOT Change current setting */ 05179 return -1; 05180 } else { 05181 if (option_debug > 2) 05182 ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n"); 05183 return 0; 05184 } 05185 } 05186 05187 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 05188 they are acceptable */ 05189 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 05190 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 05191 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 05192 05193 ast_rtp_pt_copy(p->rtp, newaudiortp); 05194 if (p->vrtp) 05195 ast_rtp_pt_copy(p->vrtp, newvideortp); 05196 05197 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 05198 ast_clear_flag(&p->flags[0], SIP_DTMF); 05199 if (newnoncodeccapability & AST_RTP_DTMF) { 05200 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 05201 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 05202 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 05203 ast_rtp_setdtmf(p->rtp, 1); 05204 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05205 } else { 05206 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 05207 } 05208 } 05209 05210 /* Setup audio port number */ 05211 if (p->rtp && sin.sin_port) { 05212 ast_rtp_set_peer(p->rtp, &sin); 05213 if (debug) 05214 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05215 } 05216 05217 /* Setup video port number */ 05218 if (p->vrtp && vsin.sin_port) { 05219 ast_rtp_set_peer(p->vrtp, &vsin); 05220 if (debug) 05221 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 05222 } 05223 05224 /* Ok, we're going with this offer */ 05225 if (option_debug > 1) { 05226 char buf[BUFSIZ]; 05227 ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, BUFSIZ, p->jointcapability)); 05228 } 05229 05230 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 05231 return 0; 05232 05233 if (option_debug > 3) 05234 ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n"); 05235 05236 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05237 if (debug) { 05238 char s1[BUFSIZ], s2[BUFSIZ]; 05239 ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 05240 ast_getformatname_multiple(s1, BUFSIZ, p->jointcapability), 05241 ast_getformatname_multiple(s2, BUFSIZ, p->owner->nativeformats)); 05242 } 05243 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); 05244 ast_set_read_format(p->owner, p->owner->readformat); 05245 ast_set_write_format(p->owner, p->owner->writeformat); 05246 } 05247 05248 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 05249 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 05250 /* Activate a re-invite */ 05251 ast_queue_frame(p->owner, &ast_null_frame); 05252 } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { 05253 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 05254 S_OR(p->mohsuggest, NULL), 05255 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 05256 if (sendonly) 05257 ast_rtp_stop(p->rtp); 05258 /* RTCP needs to go ahead, even if we're on hold!!! */ 05259 /* Activate a re-invite */ 05260 ast_queue_frame(p->owner, &ast_null_frame); 05261 } 05262 05263 /* Manager Hold and Unhold events must be generated, if necessary */ 05264 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 05265 append_history(p, "Unhold", "%s", req->data); 05266 if (global_callevents) 05267 manager_event(EVENT_FLAG_CALL, "Unhold", 05268 "Channel: %s\r\n" 05269 "Uniqueid: %s\r\n", 05270 p->owner->name, 05271 p->owner->uniqueid); 05272 if (global_notifyhold) 05273 sip_peer_hold(p, 0); 05274 ast_clear_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 05275 } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { 05276 /* No address for RTP, we're on hold */ 05277 append_history(p, "Hold", "%s", req->data); 05278 05279 if (global_callevents && !ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 05280 manager_event(EVENT_FLAG_CALL, "Hold", 05281 "Channel: %s\r\n" 05282 "Uniqueid: %s\r\n", 05283 p->owner->name, 05284 p->owner->uniqueid); 05285 } 05286 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 05287 ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 05288 else if (sendonly == 2) /* Inactive stream */ 05289 ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 05290 else 05291 ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 05292 if (global_notifyhold) 05293 sip_peer_hold(p, 1); 05294 } 05295 05296 return 0; 05297 }
static struct sip_peer * realtime_peer | ( | const char * | newpeername, | |
struct sockaddr_in * | sin | |||
) | [static] |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
Definition at line 2408 of file chan_sip.c.
References ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), ipaddr, ast_variable::name, ast_variable::next, ast_variable::value, and var.
02409 { 02410 struct sip_peer *peer; 02411 struct ast_variable *var = NULL; 02412 struct ast_variable *tmp; 02413 char ipaddr[INET_ADDRSTRLEN]; 02414 02415 /* First check on peer name */ 02416 if (newpeername) 02417 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 02418 else if (sin) { /* Then check on IP address for dynamic peers */ 02419 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 02420 var = ast_load_realtime("sippeers", "host", ipaddr, NULL); /* First check for fixed IP hosts */ 02421 if (!var) 02422 var = ast_load_realtime("sippeers", "ipaddr", ipaddr, NULL); /* Then check for registred hosts */ 02423 } 02424 02425 if (!var) 02426 return NULL; 02427 02428 for (tmp = var; tmp; tmp = tmp->next) { 02429 /* If this is type=user, then skip this object. */ 02430 if (!strcasecmp(tmp->name, "type") && 02431 !strcasecmp(tmp->value, "user")) { 02432 ast_variables_destroy(var); 02433 return NULL; 02434 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 02435 newpeername = tmp->value; 02436 } 02437 } 02438 02439 if (!newpeername) { /* Did not find peer in realtime */ 02440 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", ipaddr); 02441 ast_variables_destroy(var); 02442 return NULL; 02443 } 02444 02445 /* Peer found in realtime, now build it in memory */ 02446 peer = build_peer(newpeername, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02447 if (!peer) { 02448 ast_variables_destroy(var); 02449 return NULL; 02450 } 02451 02452 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02453 /* Cache peer */ 02454 ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 02455 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 02456 if (peer->expire > -1) { 02457 ast_sched_del(sched, peer->expire); 02458 } 02459 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, (void *)peer); 02460 } 02461 ASTOBJ_CONTAINER_LINK(&peerl,peer); 02462 } else { 02463 ast_set_flag(&peer->flags[0], SIP_REALTIME); 02464 } 02465 ast_variables_destroy(var); 02466 02467 return peer; 02468 }
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 2293 of file chan_sip.c.
References ast_config_AST_SYSTEM_NAME, ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, ast_update_realtime(), global_flags, ipaddr, and SIP_PAGE2_RTSAVE_SYSNAME.
02294 { 02295 char port[10]; 02296 char ipaddr[INET_ADDRSTRLEN]; 02297 char regseconds[20]; 02298 02299 char *sysname = ast_config_AST_SYSTEM_NAME; 02300 char *syslabel = NULL; 02301 02302 time_t nowtime = time(NULL) + expirey; 02303 const char *fc = fullcontact ? "fullcontact" : NULL; 02304 02305 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 02306 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 02307 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02308 02309 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 02310 sysname = NULL; 02311 else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME)) 02312 syslabel = "regserver"; 02313 02314 if (fc) 02315 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02316 "port", port, "regseconds", regseconds, 02317 "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */ 02318 else 02319 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02320 "port", port, "regseconds", regseconds, 02321 "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */ 02322 }
static struct sip_user * realtime_user | ( | const char * | username | ) | [static] |
Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped).
Definition at line 2518 of file chan_sip.c.
References ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, ast_variable::value, and var.
02519 { 02520 struct ast_variable *var; 02521 struct ast_variable *tmp; 02522 struct sip_user *user = NULL; 02523 02524 var = ast_load_realtime("sipusers", "name", username, NULL); 02525 02526 if (!var) 02527 return NULL; 02528 02529 for (tmp = var; tmp; tmp = tmp->next) { 02530 if (!strcasecmp(tmp->name, "type") && 02531 !strcasecmp(tmp->value, "peer")) { 02532 ast_variables_destroy(var); 02533 return NULL; 02534 } 02535 } 02536 02537 user = build_user(username, var, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02538 02539 if (!user) { /* No user found */ 02540 ast_variables_destroy(var); 02541 return NULL; 02542 } 02543 02544 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02545 ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02546 suserobjs++; 02547 ASTOBJ_CONTAINER_LINK(&userl,user); 02548 } else { 02549 /* Move counter from s to r... */ 02550 suserobjs--; 02551 ruserobjs++; 02552 ast_set_flag(&user->flags[0], SIP_REALTIME); 02553 } 02554 ast_variables_destroy(var); 02555 return user; 02556 }
static void receive_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 9332 of file chan_sip.c.
References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose(), DEFAULT_TRANS_TIMEOUT, f, get_header(), get_msg_text(), LOG_WARNING, sip_pvt::owner, sip_debug_test_pvt(), sip_scheddestroy(), and transmit_response().
Referenced by handle_request_message().
09333 { 09334 char buf[1024]; 09335 struct ast_frame f; 09336 const char *content_type = get_header(req, "Content-Type"); 09337 09338 if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */ 09339 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 09340 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09341 return; 09342 } 09343 09344 if (get_msg_text(buf, sizeof(buf), req)) { 09345 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 09346 transmit_response(p, "202 Accepted", req); 09347 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09348 return; 09349 } 09350 09351 if (p->owner) { 09352 if (sip_debug_test_pvt(p)) 09353 ast_verbose("Message received: '%s'\n", buf); 09354 memset(&f, 0, sizeof(f)); 09355 f.frametype = AST_FRAME_TEXT; 09356 f.subclass = 0; 09357 f.offset = 0; 09358 f.data = buf; 09359 f.datalen = strlen(buf); 09360 ast_queue_frame(p->owner, &f); 09361 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 09362 } else { /* Message outside of a call, we do not support that */ 09363 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); 09364 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 09365 } 09366 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09367 return; 09368 }
static char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 1605 of file chan_sip.c.
References referstatusstrings, and text.
Referenced by __sip_show_channels().
01606 { 01607 int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0])); 01608 int x; 01609 01610 for (x = 0; x < i; x++) { 01611 if (referstatusstrings[x].status == rstatus) 01612 return (char *) referstatusstrings[x].text; 01613 } 01614 return ""; 01615 }
static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 7621 of file chan_sip.c.
References sip_peer::addr, ast_db_get(), ast_device_state_changed(), ast_inet_ntoa(), ast_log(), ast_random(), ast_sched_add(), ast_sched_del(), ast_test_flag, sip_peer::expire, expire_register(), sip_peer::flags, sip_peer::fullcontact, LOG_DEBUG, option_debug, sip_peer::pokeexpire, register_peer_exten(), sched, SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, strsep(), TRUE, sip_peer::username, and username.
07622 { 07623 char data[256]; 07624 struct in_addr in; 07625 int expiry; 07626 int port; 07627 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 07628 07629 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07630 return; 07631 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 07632 return; 07633 07634 scan = data; 07635 addr = strsep(&scan, ":"); 07636 port_str = strsep(&scan, ":"); 07637 expiry_str = strsep(&scan, ":"); 07638 username = strsep(&scan, ":"); 07639 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 07640 07641 if (!inet_aton(addr, &in)) 07642 return; 07643 07644 if (port_str) 07645 port = atoi(port_str); 07646 else 07647 return; 07648 07649 if (expiry_str) 07650 expiry = atoi(expiry_str); 07651 else 07652 return; 07653 07654 if (username) 07655 ast_copy_string(peer->username, username, sizeof(peer->username)); 07656 if (contact) 07657 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 07658 07659 if (option_debug > 1) 07660 ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 07661 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 07662 07663 memset(&peer->addr, 0, sizeof(peer->addr)); 07664 peer->addr.sin_family = AF_INET; 07665 peer->addr.sin_addr = in; 07666 peer->addr.sin_port = htons(port); 07667 if (sipsock < 0) { 07668 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 07669 if (peer->pokeexpire > -1) 07670 ast_sched_del(sched, peer->pokeexpire); 07671 peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer); 07672 } else 07673 sip_poke_peer(peer); 07674 if (peer->expire > -1) 07675 ast_sched_del(sched, peer->expire); 07676 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 07677 register_peer_exten(peer, TRUE); 07678 ast_device_state_changed("SIP/%s", peer->name); 07679 }
static void register_peer_exten | ( | struct sip_peer * | peer, | |
int | onoff | |||
) | [static] |
Automatically add peer extension to dial plan.
Definition at line 2325 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().
02326 { 02327 char multi[256]; 02328 char *stringp, *ext, *context; 02329 02330 /* XXX note that global_regcontext is both a global 'enable' flag and 02331 * the name of the global regexten context, if not specified 02332 * individually. 02333 */ 02334 if (ast_strlen_zero(global_regcontext)) 02335 return; 02336 02337 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 02338 stringp = multi; 02339 while ((ext = strsep(&stringp, "&"))) { 02340 if ((context = strchr(ext, '@'))) { 02341 *context++ = '\0'; /* split ext@context */ 02342 if (!ast_context_find(context)) { 02343 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 02344 continue; 02345 } 02346 } else { 02347 context = global_regcontext; 02348 } 02349 if (onoff) 02350 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 02351 ast_strdup(peer->name), ast_free, "SIP"); 02352 else 02353 ast_context_remove_extension(context, ext, 1, NULL); 02354 } 02355 }
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 8271 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_NOT_FOUND, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, sip_peer::autoframing, sip_pvt::autoframing, build_contact(), check_auth(), check_sip_domain(), EVENT_FLAG_SYSTEM, exten, find_peer(), sip_pvt::flags, sip_peer::flags, get_header(), get_in_brackets(), sip_peer::ha, sip_pvt::initreq, sip_peer::lastmsgssent, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event(), sip_peer::md5secret, name, option_debug, 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.
08273 { 08274 enum check_auth_result res = AUTH_NOT_FOUND; 08275 struct sip_peer *peer; 08276 char tmp[256]; 08277 char *name, *c; 08278 char *t; 08279 char *domain; 08280 08281 /* Terminate URI */ 08282 t = uri; 08283 while(*t && (*t > 32) && (*t != ';')) 08284 t++; 08285 *t = '\0'; 08286 08287 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 08288 if (pedanticsipchecking) 08289 ast_uri_decode(tmp); 08290 08291 c = get_in_brackets(tmp); 08292 c = strsep(&c, ";"); /* Ditch ;user=phone */ 08293 08294 if (!strncmp(c, "sip:", 4)) { 08295 name = c + 4; 08296 } else { 08297 name = c; 08298 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 08299 } 08300 08301 /* Strip off the domain name */ 08302 if ((c = strchr(name, '@'))) { 08303 *c++ = '\0'; 08304 domain = c; 08305 if ((c = strchr(domain, ':'))) /* Remove :port */ 08306 *c = '\0'; 08307 if (!AST_LIST_EMPTY(&domain_list)) { 08308 if (!check_sip_domain(domain, NULL, 0)) { 08309 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 08310 return AUTH_UNKNOWN_DOMAIN; 08311 } 08312 } 08313 } 08314 08315 ast_string_field_set(p, exten, name); 08316 build_contact(p); 08317 peer = find_peer(name, NULL, 1); 08318 if (!(peer && ast_apply_ha(peer->ha, sin))) { 08319 /* Peer fails ACL check */ 08320 if (peer) 08321 ASTOBJ_UNREF(peer, sip_destroy_peer); 08322 peer = NULL; 08323 } 08324 if (peer) { 08325 /* Set Frame packetization */ 08326 if (p->rtp) { 08327 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 08328 p->autoframing = peer->autoframing; 08329 } 08330 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 08331 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 08332 } else { 08333 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 08334 transmit_response(p, "100 Trying", req); 08335 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { 08336 sip_cancel_destroy(p); 08337 08338 /* We have a succesful registration attemp with proper authentication, 08339 now, update the peer */ 08340 switch (parse_register_contact(p, peer, req)) { 08341 case PARSE_REGISTER_FAILED: 08342 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08343 transmit_response_with_date(p, "400 Bad Request", req); 08344 peer->lastmsgssent = -1; 08345 res = 0; 08346 break; 08347 case PARSE_REGISTER_QUERY: 08348 transmit_response_with_date(p, "200 OK", req); 08349 peer->lastmsgssent = -1; 08350 res = 0; 08351 break; 08352 case PARSE_REGISTER_UPDATE: 08353 update_peer(peer, p->expiry); 08354 /* Say OK and ask subsystem to retransmit msg counter */ 08355 transmit_response_with_date(p, "200 OK", req); 08356 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 08357 peer->lastmsgssent = -1; 08358 res = 0; 08359 break; 08360 } 08361 } 08362 } 08363 } 08364 if (!peer && autocreatepeer) { 08365 /* Create peer if we have autocreate mode enabled */ 08366 peer = temp_peer(name); 08367 if (peer) { 08368 ASTOBJ_CONTAINER_LINK(&peerl, peer); 08369 sip_cancel_destroy(p); 08370 switch (parse_register_contact(p, peer, req)) { 08371 case PARSE_REGISTER_FAILED: 08372 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08373 transmit_response_with_date(p, "400 Bad Request", req); 08374 peer->lastmsgssent = -1; 08375 res = 0; 08376 break; 08377 case PARSE_REGISTER_QUERY: 08378 transmit_response_with_date(p, "200 OK", req); 08379 peer->lastmsgssent = -1; 08380 res = 0; 08381 break; 08382 case PARSE_REGISTER_UPDATE: 08383 /* Say OK and ask subsystem to retransmit msg counter */ 08384 transmit_response_with_date(p, "200 OK", req); 08385 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08386 peer->lastmsgssent = -1; 08387 res = 0; 08388 break; 08389 } 08390 } 08391 } 08392 if (!res) { 08393 ast_device_state_changed("SIP/%s", peer->name); 08394 } 08395 if (res < 0) { 08396 switch (res) { 08397 case AUTH_SECRET_FAILED: 08398 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 08399 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08400 break; 08401 case AUTH_USERNAME_MISMATCH: 08402 /* Username and digest username does not match. 08403 Asterisk uses the From: username for authentication. We need the 08404 users to use the same authentication user name until we support 08405 proper authentication by digest auth name */ 08406 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 08407 break; 08408 case AUTH_NOT_FOUND: 08409 if (global_alwaysauthreject) { 08410 transmit_fake_auth_response(p, &p->initreq, 1); 08411 } else { 08412 /* URI not found */ 08413 transmit_response(p, "404 Not found", &p->initreq); 08414 } 08415 break; 08416 default: 08417 break; 08418 } 08419 if (option_debug > 1) { 08420 const char *reason = ""; 08421 08422 switch (res) { 08423 case AUTH_SECRET_FAILED: 08424 reason = "Bad password"; 08425 break; 08426 case AUTH_USERNAME_MISMATCH: 08427 reason = "Bad digest user"; 08428 break; 08429 case AUTH_NOT_FOUND: 08430 reason = "Peer not found"; 08431 break; 08432 default: 08433 break; 08434 } 08435 ast_log(LOG_DEBUG, "SIP REGISTER attempt failed for %s : %s\n", 08436 peer->name, reason); 08437 } 08438 } 08439 if (peer) 08440 ASTOBJ_UNREF(peer, sip_destroy_peer); 08441 08442 return res; 08443 }
static char * regstate2str | ( | enum sipregistrystate | regstate | ) | const [static] |
Convert registration state status to string.
Definition at line 7122 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.
07123 { 07124 switch(regstate) { 07125 case REG_STATE_FAILED: 07126 return "Failed"; 07127 case REG_STATE_UNREGISTERED: 07128 return "Unregistered"; 07129 case REG_STATE_REGSENT: 07130 return "Request Sent"; 07131 case REG_STATE_AUTHSENT: 07132 return "Auth. Sent"; 07133 case REG_STATE_REGISTERED: 07134 return "Registered"; 07135 case REG_STATE_REJECTED: 07136 return "Rejected"; 07137 case REG_STATE_TIMEOUT: 07138 return "Timeout"; 07139 case REG_STATE_NOAUTH: 07140 return "No Authentication"; 07141 default: 07142 return "Unknown"; 07143 } 07144 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 17295 of file chan_sip.c.
References sip_reload().
17296 { 17297 return sip_reload(0, 0, NULL); 17298 }
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 16204 of file chan_sip.c.
References ahp, ast_clear_flag, ast_config_AST_SYSTEM_NAME, ast_config_load(), ast_copy_flags, AST_FLAGS_ALL, ast_jb_read_conf(), ast_log(), AST_MAX_CONTEXT, ast_set_flag, ast_strlen_zero(), ast_true(), ast_variable_browse(), bindaddr, context, DEFAULT_ALLOW_EXT_DOM, DEFAULT_ALLOWGUEST, DEFAULT_AUTOCREATEPEER, DEFAULT_CALLERID, DEFAULT_COMPACTHEADERS, DEFAULT_CONTEXT, DEFAULT_EXPIRY, default_jbconf, DEFAULT_MAX_CALL_BITRATE, DEFAULT_MOHINTERPRET, DEFAULT_MOHSUGGEST, DEFAULT_MWITIME, DEFAULT_NOTIFYMIME, DEFAULT_NOTIFYRINGING, DEFAULT_PEDANTIC, default_prefs, DEFAULT_QUALIFY, DEFAULT_REALM, DEFAULT_REGISTRATION_TIMEOUT, DEFAULT_SRVLOOKUP, DEFAULT_T1MIN, DEFAULT_TOS_AUDIO, DEFAULT_TOS_SIP, DEFAULT_TOS_VIDEO, DEFAULT_USERAGENT, DEFAULT_VMEXTEN, externexpire, externhost, externip, externrefresh, FALSE, global_flags, global_jbconf, handle_common_options(), hp, localaddr, LOG_NOTICE, ast_variable::name, ast_variable::next, ourport, outboundproxyip, SIP_CAN_REINVITE, SIP_DTMF_RFC2833, SIP_NAT_RFC3581, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DEBUG_CONFIG, SIP_PAGE2_DEBUG_CONSOLE, SIP_PAGE2_RTUPDATE, SIP_PAGE2_VIDEOSUPPORT, STANDARD_SIP_PORT, TRANSFER_OPENFORALL, and ast_variable::value.
16205 { 16206 struct ast_config *cfg, *ucfg; 16207 struct ast_variable *v; 16208 struct sip_peer *peer; 16209 struct sip_user *user; 16210 struct ast_hostent ahp; 16211 char *cat, *stringp, *context, *oldregcontext; 16212 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 16213 struct hostent *hp; 16214 int format; 16215 struct ast_flags dummy[2]; 16216 int auto_sip_domains = FALSE; 16217 struct sockaddr_in old_bindaddr = bindaddr; 16218 int registry_count = 0, peer_count = 0, user_count = 0; 16219 unsigned int temp_tos = 0; 16220 struct ast_flags debugflag = {0}; 16221 16222 cfg = ast_config_load(config); 16223 16224 /* We *must* have a config file otherwise stop immediately */ 16225 if (!cfg) { 16226 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 16227 return -1; 16228 } 16229 16230 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 16231 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 16232 oldregcontext = oldcontexts; 16233 16234 /* Clear all flags before setting default values */ 16235 /* Preserve debugging settings for console */ 16236 ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 16237 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 16238 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 16239 ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE); 16240 16241 /* Reset IP addresses */ 16242 memset(&bindaddr, 0, sizeof(bindaddr)); 16243 memset(&localaddr, 0, sizeof(localaddr)); 16244 memset(&externip, 0, sizeof(externip)); 16245 memset(&default_prefs, 0 , sizeof(default_prefs)); 16246 outboundproxyip.sin_port = htons(STANDARD_SIP_PORT); 16247 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 16248 ourport = STANDARD_SIP_PORT; 16249 srvlookup = DEFAULT_SRVLOOKUP; 16250 global_tos_sip = DEFAULT_TOS_SIP; 16251 global_tos_audio = DEFAULT_TOS_AUDIO; 16252 global_tos_video = DEFAULT_TOS_VIDEO; 16253 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 16254 externexpire = 0; /* Expiration for DNS re-issuing */ 16255 externrefresh = 10; 16256 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 16257 16258 /* Reset channel settings to default before re-configuring */ 16259 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 16260 global_regcontext[0] = '\0'; 16261 expiry = DEFAULT_EXPIRY; 16262 global_notifyringing = DEFAULT_NOTIFYRINGING; 16263 global_limitonpeers = FALSE; 16264 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 16265 global_notifyhold = FALSE; 16266 global_alwaysauthreject = 0; 16267 global_allowsubscribe = FALSE; 16268 ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent)); 16269 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 16270 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) 16271 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 16272 else 16273 ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm)); 16274 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 16275 compactheaders = DEFAULT_COMPACTHEADERS; 16276 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 16277 global_regattempts_max = 0; 16278 pedanticsipchecking = DEFAULT_PEDANTIC; 16279 global_mwitime = DEFAULT_MWITIME; 16280 autocreatepeer = DEFAULT_AUTOCREATEPEER; 16281 global_autoframing = 0; 16282 global_allowguest = DEFAULT_ALLOWGUEST; 16283 global_rtptimeout = 0; 16284 global_rtpholdtimeout = 0; 16285 global_rtpkeepalive = 0; 16286 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 16287 global_rtautoclear = 120; 16288 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 16289 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 16290 ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE); 16291 16292 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 16293 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 16294 default_subscribecontext[0] = '\0'; 16295 default_language[0] = '\0'; 16296 default_fromdomain[0] = '\0'; 16297 default_qualify = DEFAULT_QUALIFY; 16298 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 16299 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 16300 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 16301 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 16302 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 16303 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 16304 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 16305 16306 /* Debugging settings, always default to off */ 16307 dumphistory = FALSE; 16308 recordhistory = FALSE; 16309 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 16310 16311 /* Misc settings for the channel */ 16312 global_relaxdtmf = FALSE; 16313 global_callevents = FALSE; 16314 global_t1min = DEFAULT_T1MIN; 16315 16316 global_matchexterniplocally = FALSE; 16317 16318 /* Copy the default jb config over global_jbconf */ 16319 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 16320 16321 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 16322 16323 /* Read the [general] config section of sip.conf (or from realtime config) */ 16324 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 16325 if (handle_common_options(&global_flags[0], &dummy[0], v)) 16326 continue; 16327 /* handle jb conf */ 16328 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 16329 continue; 16330 16331 /* Create the interface list */ 16332 if (!strcasecmp(v->name, "context")) { 16333 ast_copy_string(default_context, v->value, sizeof(default_context)); 16334 } else if (!strcasecmp(v->name, "allowguest")) { 16335 global_allowguest = ast_true(v->value) ? 1 : 0; 16336 } else if (!strcasecmp(v->name, "realm")) { 16337 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 16338 } else if (!strcasecmp(v->name, "useragent")) { 16339 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 16340 if (option_debug) 16341 ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 16342 } else if (!strcasecmp(v->name, "allowtransfer")) { 16343 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16344 } else if (!strcasecmp(v->name, "rtcachefriends")) { 16345 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 16346 } else if (!strcasecmp(v->name, "rtsavesysname")) { 16347 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME); 16348 } else if (!strcasecmp(v->name, "rtupdate")) { 16349 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE); 16350 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 16351 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 16352 } else if (!strcasecmp(v->name, "t1min")) { 16353 global_t1min = atoi(v->value); 16354 } else if (!strcasecmp(v->name, "rtautoclear")) { 16355 int i = atoi(v->value); 16356 if (i > 0) 16357 global_rtautoclear = i; 16358 else 16359 i = 0; 16360 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 16361 } else if (!strcasecmp(v->name, "usereqphone")) { 16362 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 16363 } else if (!strcasecmp(v->name, "relaxdtmf")) { 16364 global_relaxdtmf = ast_true(v->value); 16365 } else if (!strcasecmp(v->name, "checkmwi")) { 16366 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 16367 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 16368 global_mwitime = DEFAULT_MWITIME; 16369 } 16370 } else if (!strcasecmp(v->name, "vmexten")) { 16371 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 16372 } else if (!strcasecmp(v->name, "rtptimeout")) { 16373 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 16374 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16375 global_rtptimeout = 0; 16376 } 16377 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 16378 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 16379 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16380 global_rtpholdtimeout = 0; 16381 } 16382 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 16383 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 16384 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 16385 global_rtpkeepalive = 0; 16386 } 16387 } else if (!strcasecmp(v->name, "compactheaders")) { 16388 compactheaders = ast_true(v->value); 16389 } else if (!strcasecmp(v->name, "notifymimetype")) { 16390 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 16391 } else if (!strncasecmp(v->name, "limitonpeer", 11)) { 16392 global_limitonpeers = ast_true(v->value); 16393 } else if (!strcasecmp(v->name, "directrtpsetup")) { 16394 global_directrtpsetup = ast_true(v->value); 16395 } else if (!strcasecmp(v->name, "notifyringing")) { 16396 global_notifyringing = ast_true(v->value); 16397 } else if (!strcasecmp(v->name, "notifyhold")) { 16398 global_notifyhold = ast_true(v->value); 16399 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 16400 global_alwaysauthreject = ast_true(v->value); 16401 } else if (!strcasecmp(v->name, "mohinterpret") 16402 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16403 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 16404 } else if (!strcasecmp(v->name, "mohsuggest")) { 16405 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 16406 } else if (!strcasecmp(v->name, "language")) { 16407 ast_copy_string(default_language, v->value, sizeof(default_language)); 16408 } else if (!strcasecmp(v->name, "regcontext")) { 16409 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 16410 stringp = newcontexts; 16411 /* Let's remove any contexts that are no longer defined in regcontext */ 16412 cleanup_stale_contexts(stringp, oldregcontext); 16413 /* Create contexts if they don't exist already */ 16414 while ((context = strsep(&stringp, "&"))) { 16415 if (!ast_context_find(context)) 16416 ast_context_create(NULL, context,"SIP"); 16417 } 16418 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 16419 } else if (!strcasecmp(v->name, "callerid")) { 16420 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 16421 } else if (!strcasecmp(v->name, "fromdomain")) { 16422 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 16423 } else if (!strcasecmp(v->name, "outboundproxy")) { 16424 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 16425 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 16426 } else if (!strcasecmp(v->name, "outboundproxyport")) { 16427 /* Port needs to be after IP */ 16428 sscanf(v->value, "%d", &format); 16429 outboundproxyip.sin_port = htons(format); 16430 } else if (!strcasecmp(v->name, "autocreatepeer")) { 16431 autocreatepeer = ast_true(v->value); 16432 } else if (!strcasecmp(v->name, "srvlookup")) { 16433 srvlookup = ast_true(v->value); 16434 } else if (!strcasecmp(v->name, "pedantic")) { 16435 pedanticsipchecking = ast_true(v->value); 16436 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 16437 max_expiry = atoi(v->value); 16438 if (max_expiry < 1) 16439 max_expiry = DEFAULT_MAX_EXPIRY; 16440 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 16441 min_expiry = atoi(v->value); 16442 if (min_expiry < 1) 16443 min_expiry = DEFAULT_MIN_EXPIRY; 16444 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 16445 default_expiry = atoi(v->value); 16446 if (default_expiry < 1) 16447 default_expiry = DEFAULT_DEFAULT_EXPIRY; 16448 } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */ 16449 if (ast_true(v->value)) 16450 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 16451 } else if (!strcasecmp(v->name, "dumphistory")) { 16452 dumphistory = ast_true(v->value); 16453 } else if (!strcasecmp(v->name, "recordhistory")) { 16454 recordhistory = ast_true(v->value); 16455 } else if (!strcasecmp(v->name, "registertimeout")) { 16456 global_reg_timeout = atoi(v->value); 16457 if (global_reg_timeout < 1) 16458 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 16459 } else if (!strcasecmp(v->name, "registerattempts")) { 16460 global_regattempts_max = atoi(v->value); 16461 } else if (!strcasecmp(v->name, "bindaddr")) { 16462 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 16463 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 16464 } else { 16465 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 16466 } 16467 } else if (!strcasecmp(v->name, "localnet")) { 16468 struct ast_ha *na; 16469 if (!(na = ast_append_ha("d", v->value, localaddr))) 16470 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 16471 else 16472 localaddr = na; 16473 } else if (!strcasecmp(v->name, "localmask")) { 16474 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 16475 } else if (!strcasecmp(v->name, "externip")) { 16476 if (!(hp = ast_gethostbyname(v->value, &ahp))) 16477 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 16478 else 16479 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 16480 externexpire = 0; 16481 } else if (!strcasecmp(v->name, "externhost")) { 16482 ast_copy_string(externhost, v->value, sizeof(externhost)); 16483 if (!(hp = ast_gethostbyname(externhost, &ahp))) 16484 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 16485 else 16486 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 16487 externexpire = time(NULL); 16488 } else if (!strcasecmp(v->name, "externrefresh")) { 16489 if (sscanf(v->value, "%d", &externrefresh) != 1) { 16490 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 16491 externrefresh = 10; 16492 } 16493 } else if (!strcasecmp(v->name, "allow")) { 16494 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1); 16495 } else if (!strcasecmp(v->name, "disallow")) { 16496 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0); 16497 } else if (!strcasecmp(v->name, "autoframing")) { 16498 global_autoframing = ast_true(v->value); 16499 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 16500 allow_external_domains = ast_true(v->value); 16501 } else if (!strcasecmp(v->name, "autodomain")) { 16502 auto_sip_domains = ast_true(v->value); 16503 } else if (!strcasecmp(v->name, "domain")) { 16504 char *domain = ast_strdupa(v->value); 16505 char *context = strchr(domain, ','); 16506 16507 if (context) 16508 *context++ = '\0'; 16509 16510 if (option_debug && ast_strlen_zero(context)) 16511 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 16512 if (ast_strlen_zero(domain)) 16513 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 16514 else 16515 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 16516 } else if (!strcasecmp(v->name, "register")) { 16517 if (sip_register(v->value, v->lineno) == 0) 16518 registry_count++; 16519 } else if (!strcasecmp(v->name, "tos")) { 16520 if (!ast_str2tos(v->value, &temp_tos)) { 16521 global_tos_sip = temp_tos; 16522 global_tos_audio = temp_tos; 16523 global_tos_video = temp_tos; 16524 ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno); 16525 } else 16526 ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno); 16527 } else if (!strcasecmp(v->name, "tos_sip")) { 16528 if (ast_str2tos(v->value, &global_tos_sip)) 16529 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); 16530 } else if (!strcasecmp(v->name, "tos_audio")) { 16531 if (ast_str2tos(v->value, &global_tos_audio)) 16532 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); 16533 } else if (!strcasecmp(v->name, "tos_video")) { 16534 if (ast_str2tos(v->value, &global_tos_video)) 16535 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); 16536 } else if (!strcasecmp(v->name, "bindport")) { 16537 if (sscanf(v->value, "%d", &ourport) == 1) { 16538 bindaddr.sin_port = htons(ourport); 16539 } else { 16540 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 16541 } 16542 } else if (!strcasecmp(v->name, "qualify")) { 16543 if (!strcasecmp(v->value, "no")) { 16544 default_qualify = 0; 16545 } else if (!strcasecmp(v->value, "yes")) { 16546 default_qualify = DEFAULT_MAXMS; 16547 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 16548 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 16549 default_qualify = 0; 16550 } 16551 } else if (!strcasecmp(v->name, "callevents")) { 16552 global_callevents = ast_true(v->value); 16553 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16554 default_maxcallbitrate = atoi(v->value); 16555 if (default_maxcallbitrate < 0) 16556 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 16557 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 16558 global_matchexterniplocally = ast_true(v->value); 16559 } 16560 } 16561 16562 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 16563 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 16564 allow_external_domains = 1; 16565 } 16566 16567 /* Build list of authentication to various SIP realms, i.e. service providers */ 16568 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 16569 /* Format for authentication is auth = username:password@realm */ 16570 if (!strcasecmp(v->name, "auth")) 16571 authl = add_realm_authentication(authl, v->value, v->lineno); 16572 } 16573 16574 ucfg = ast_config_load("users.conf"); 16575 if (ucfg) { 16576 struct ast_variable *gen; 16577 int genhassip, genregistersip; 16578 const char *hassip, *registersip; 16579 16580 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 16581 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 16582 gen = ast_variable_browse(ucfg, "general"); 16583 cat = ast_category_browse(ucfg, NULL); 16584 while (cat) { 16585 if (strcasecmp(cat, "general")) { 16586 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 16587 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 16588 if (ast_true(hassip) || (!hassip && genhassip)) { 16589 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 16590 if (peer) { 16591 ast_device_state_changed("SIP/%s", peer->name); 16592 ASTOBJ_CONTAINER_LINK(&peerl,peer); 16593 ASTOBJ_UNREF(peer, sip_destroy_peer); 16594 peer_count++; 16595 } 16596 } 16597 if (ast_true(registersip) || (!registersip && genregistersip)) { 16598 char tmp[256]; 16599 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 16600 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 16601 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 16602 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 16603 if (!host) 16604 host = ast_variable_retrieve(ucfg, "general", "host"); 16605 if (!username) 16606 username = ast_variable_retrieve(ucfg, "general", "username"); 16607 if (!secret) 16608 secret = ast_variable_retrieve(ucfg, "general", "secret"); 16609 if (!contact) 16610 contact = "s"; 16611 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 16612 if (!ast_strlen_zero(secret)) 16613 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 16614 else 16615 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 16616 if (sip_register(tmp, 0) == 0) 16617 registry_count++; 16618 } 16619 } 16620 } 16621 cat = ast_category_browse(ucfg, cat); 16622 } 16623 ast_config_destroy(ucfg); 16624 } 16625 16626 16627 /* Load peers, users and friends */ 16628 cat = NULL; 16629 while ( (cat = ast_category_browse(cfg, cat)) ) { 16630 const char *utype; 16631 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 16632 continue; 16633 utype = ast_variable_retrieve(cfg, cat, "type"); 16634 if (!utype) { 16635 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 16636 continue; 16637 } else { 16638 int is_user = 0, is_peer = 0; 16639 if (!strcasecmp(utype, "user")) 16640 is_user = 1; 16641 else if (!strcasecmp(utype, "friend")) 16642 is_user = is_peer = 1; 16643 else if (!strcasecmp(utype, "peer")) 16644 is_peer = 1; 16645 else { 16646 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 16647 continue; 16648 } 16649 if (is_user) { 16650 user = build_user(cat, ast_variable_browse(cfg, cat), 0); 16651 if (user) { 16652 ASTOBJ_CONTAINER_LINK(&userl,user); 16653 ASTOBJ_UNREF(user, sip_destroy_user); 16654 user_count++; 16655 } 16656 } 16657 if (is_peer) { 16658 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 16659 if (peer) { 16660 ASTOBJ_CONTAINER_LINK(&peerl,peer); 16661 ASTOBJ_UNREF(peer, sip_destroy_peer); 16662 peer_count++; 16663 } 16664 } 16665 } 16666 } 16667 if (ast_find_ourip(&__ourip, bindaddr)) { 16668 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 16669 return 0; 16670 } 16671 if (!ntohs(bindaddr.sin_port)) 16672 bindaddr.sin_port = ntohs(STANDARD_SIP_PORT); 16673 bindaddr.sin_family = AF_INET; 16674 ast_mutex_lock(&netlock); 16675 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 16676 close(sipsock); 16677 sipsock = -1; 16678 } 16679 if (sipsock < 0) { 16680 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 16681 if (sipsock < 0) { 16682 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 16683 return -1; 16684 } else { 16685 /* Allow SIP clients on the same host to access us: */ 16686 const int reuseFlag = 1; 16687 16688 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 16689 (const char*)&reuseFlag, 16690 sizeof reuseFlag); 16691 16692 ast_enable_packet_fragmentation(sipsock); 16693 16694 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 16695 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 16696 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 16697 strerror(errno)); 16698 close(sipsock); 16699 sipsock = -1; 16700 } else { 16701 if (option_verbose > 1) { 16702 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 16703 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 16704 ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip)); 16705 } 16706 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 16707 ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip)); 16708 } 16709 } 16710 } 16711 ast_mutex_unlock(&netlock); 16712 16713 /* Add default domains - host name, IP address and IP:port */ 16714 /* Only do this if user added any sip domain with "localdomains" */ 16715 /* In order to *not* break backwards compatibility */ 16716 /* Some phones address us at IP only, some with additional port number */ 16717 if (auto_sip_domains) { 16718 char temp[MAXHOSTNAMELEN]; 16719 16720 /* First our default IP address */ 16721 if (bindaddr.sin_addr.s_addr) 16722 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 16723 else 16724 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 16725 16726 /* Our extern IP address, if configured */ 16727 if (externip.sin_addr.s_addr) 16728 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 16729 16730 /* Extern host name (NAT traversal support) */ 16731 if (!ast_strlen_zero(externhost)) 16732 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 16733 16734 /* Our host name */ 16735 if (!gethostname(temp, sizeof(temp))) 16736 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 16737 } 16738 16739 /* Release configuration from memory */ 16740 ast_config_destroy(cfg); 16741 16742 /* Load the list of manual NOTIFY types to support */ 16743 if (notify_types) 16744 ast_config_destroy(notify_types); 16745 notify_types = ast_config_load(notify_config); 16746 16747 /* Done, tell the manager */ 16748 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); 16749 16750 return 0; 16751 }
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 11118 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().
11119 { 11120 char tmp[512]; 11121 char *c; 11122 char oldnonce[256]; 11123 11124 /* table of recognised keywords, and places where they should be copied */ 11125 const struct x { 11126 const char *key; 11127 int field_index; 11128 } *i, keys[] = { 11129 { "realm=", ast_string_field_index(p, realm) }, 11130 { "nonce=", ast_string_field_index(p, nonce) }, 11131 { "opaque=", ast_string_field_index(p, opaque) }, 11132 { "qop=", ast_string_field_index(p, qop) }, 11133 { "domain=", ast_string_field_index(p, domain) }, 11134 { NULL, 0 }, 11135 }; 11136 11137 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 11138 if (ast_strlen_zero(tmp)) 11139 return -1; 11140 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 11141 ast_log(LOG_WARNING, "missing Digest.\n"); 11142 return -1; 11143 } 11144 c = tmp + strlen("Digest "); 11145 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 11146 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 11147 for (i = keys; i->key != NULL; i++) { 11148 char *src, *separator; 11149 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 11150 continue; 11151 /* Found. Skip keyword, take text in quotes or up to the separator. */ 11152 c += strlen(i->key); 11153 if (*c == '"') { 11154 src = ++c; 11155 separator = "\""; 11156 } else { 11157 src = c; 11158 separator = ","; 11159 } 11160 strsep(&c, separator); /* clear separator and move ptr */ 11161 ast_string_field_index_set(p, i->field_index, src); 11162 break; 11163 } 11164 if (i->key == NULL) /* not found, try ',' */ 11165 strsep(&c, ","); 11166 } 11167 /* Reset nonce count */ 11168 if (strcmp(p->nonce, oldnonce)) 11169 p->noncecount = 0; 11170 11171 /* Save auth data for following registrations */ 11172 if (p->registry) { 11173 struct sip_registry *r = p->registry; 11174 11175 if (strcmp(r->nonce, p->nonce)) { 11176 ast_string_field_set(r, realm, p->realm); 11177 ast_string_field_set(r, nonce, p->nonce); 11178 ast_string_field_set(r, domain, p->domain); 11179 ast_string_field_set(r, opaque, p->opaque); 11180 ast_string_field_set(r, qop, p->qop); 11181 r->noncecount = 0; 11182 } 11183 } 11184 return build_reply_digest(p, sipmethod, digest, digest_len); 11185 }
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 5634 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.
05635 { 05636 struct sip_request *orig = &p->initreq; 05637 char stripped[80]; 05638 char tmp[80]; 05639 char newto[256]; 05640 const char *c; 05641 const char *ot, *of; 05642 int is_strict = FALSE; /*!< Strict routing flag */ 05643 05644 memset(req, 0, sizeof(struct sip_request)); 05645 05646 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 05647 05648 if (!seqno) { 05649 p->ocseq++; 05650 seqno = p->ocseq; 05651 } 05652 05653 if (newbranch) { 05654 p->branch ^= ast_random(); 05655 build_via(p); 05656 } 05657 05658 /* Check for strict or loose router */ 05659 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) { 05660 is_strict = TRUE; 05661 if (sipdebug) 05662 ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid); 05663 } 05664 05665 if (sipmethod == SIP_CANCEL) 05666 c = p->initreq.rlPart2; /* Use original URI */ 05667 else if (sipmethod == SIP_ACK) { 05668 /* Use URI from Contact: in 200 OK (if INVITE) 05669 (we only have the contacturi on INVITEs) */ 05670 if (!ast_strlen_zero(p->okcontacturi)) 05671 c = is_strict ? p->route->hop : p->okcontacturi; 05672 else 05673 c = p->initreq.rlPart2; 05674 } else if (!ast_strlen_zero(p->okcontacturi)) 05675 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 05676 else if (!ast_strlen_zero(p->uri)) 05677 c = p->uri; 05678 else { 05679 char *n; 05680 /* We have no URI, use To: or From: header as URI (depending on direction) */ 05681 ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"), 05682 sizeof(stripped)); 05683 n = get_in_brackets(stripped); 05684 c = strsep(&n, ";"); /* trim ; and beyond */ 05685 } 05686 init_req(req, sipmethod, c); 05687 05688 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 05689 05690 add_header(req, "Via", p->via); 05691 if (p->route) { 05692 set_destination(p, p->route->hop); 05693 add_route(req, is_strict ? p->route->next : p->route); 05694 } 05695 05696 ot = get_header(orig, "To"); 05697 of = get_header(orig, "From"); 05698 05699 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 05700 as our original request, including tag (or presumably lack thereof) */ 05701 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 05702 /* Add the proper tag if we don't have it already. If they have specified 05703 their tag, use it. Otherwise, use our own tag */ 05704 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 05705 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 05706 else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05707 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 05708 else 05709 snprintf(newto, sizeof(newto), "%s", ot); 05710 ot = newto; 05711 } 05712 05713 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 05714 add_header(req, "From", of); 05715 add_header(req, "To", ot); 05716 } else { 05717 add_header(req, "From", ot); 05718 add_header(req, "To", of); 05719 } 05720 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 05721 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 05722 add_header(req, "Contact", p->our_contact); 05723 05724 copy_header(req, orig, "Call-ID"); 05725 add_header(req, "CSeq", tmp); 05726 05727 if (!ast_strlen_zero(global_useragent)) 05728 add_header(req, "User-Agent", global_useragent); 05729 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 05730 05731 if (!ast_strlen_zero(p->rpid)) 05732 add_header(req, "Remote-Party-ID", p->rpid); 05733 05734 return 0; 05735 }
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 5586 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.
05587 { 05588 char newto[256]; 05589 const char *ot; 05590 05591 init_resp(resp, msg); 05592 copy_via_headers(p, resp, req, "Via"); 05593 if (msg[0] == '2') 05594 copy_all_header(resp, req, "Record-Route"); 05595 copy_header(resp, req, "From"); 05596 ot = get_header(req, "To"); 05597 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 05598 /* Add the proper tag if we don't have it already. If they have specified 05599 their tag, use it. Otherwise, use our own tag */ 05600 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05601 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 05602 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05603 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 05604 else 05605 ast_copy_string(newto, ot, sizeof(newto)); 05606 ot = newto; 05607 } 05608 add_header(resp, "To", ot); 05609 copy_header(resp, req, "Call-ID"); 05610 copy_header(resp, req, "CSeq"); 05611 if (!ast_strlen_zero(global_useragent)) 05612 add_header(resp, "User-Agent", global_useragent); 05613 add_header(resp, "Allow", ALLOWED_METHODS); 05614 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 05615 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 05616 /* For registration responses, we also need expiry and 05617 contact info */ 05618 char tmp[256]; 05619 05620 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 05621 add_header(resp, "Expires", tmp); 05622 if (p->expiry) { /* Only add contact if we have an expiry time */ 05623 char contact[BUFSIZ]; 05624 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 05625 add_header(resp, "Contact", contact); /* Not when we unregister */ 05626 } 05627 } else if (msg[0] != '4' && p->our_contact[0]) { 05628 add_header(resp, "Contact", p->our_contact); 05629 } 05630 return 0; 05631 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 15187 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.
15188 { 15189 /* If we're supposed to be stopped -- stay stopped */ 15190 if (monitor_thread == AST_PTHREADT_STOP) 15191 return 0; 15192 ast_mutex_lock(&monlock); 15193 if (monitor_thread == pthread_self()) { 15194 ast_mutex_unlock(&monlock); 15195 ast_log(LOG_WARNING, "Cannot kill myself\n"); 15196 return -1; 15197 } 15198 if (monitor_thread != AST_PTHREADT_NULL) { 15199 /* Wake up the thread */ 15200 pthread_kill(monitor_thread, SIGURG); 15201 } else { 15202 /* Start a new monitor */ 15203 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 15204 ast_mutex_unlock(&monlock); 15205 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 15206 return -1; 15207 } 15208 } 15209 ast_mutex_unlock(&monlock); 15210 return 0; 15211 }
static int retrans_pkt | ( | void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 1851 of file chan_sip.c.
References __sip_xmit(), append_history, 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, 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_alreadygone(), 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, and sip_pkt::timer_t1.
01852 { 01853 struct sip_pkt *pkt = data, *prev, *cur = NULL; 01854 int reschedule = DEFAULT_RETRANS; 01855 01856 /* Lock channel PVT */ 01857 ast_mutex_lock(&pkt->owner->lock); 01858 01859 if (pkt->retrans < MAX_RETRANS) { 01860 pkt->retrans++; 01861 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 01862 if (sipdebug && option_debug > 3) 01863 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); 01864 } else { 01865 int siptimer_a; 01866 01867 if (sipdebug && option_debug > 3) 01868 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 01869 if (!pkt->timer_a) 01870 pkt->timer_a = 2 ; 01871 else 01872 pkt->timer_a = 2 * pkt->timer_a; 01873 01874 /* For non-invites, a maximum of 4 secs */ 01875 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 01876 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 01877 siptimer_a = 4000; 01878 01879 /* Reschedule re-transmit */ 01880 reschedule = siptimer_a; 01881 if (option_debug > 3) 01882 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); 01883 } 01884 01885 if (sip_debug_test_pvt(pkt->owner)) { 01886 const struct sockaddr_in *dst = sip_real_dst(pkt->owner); 01887 ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n", 01888 pkt->retrans, sip_nat_mode(pkt->owner), 01889 ast_inet_ntoa(dst->sin_addr), 01890 ntohs(dst->sin_port), pkt->data); 01891 } 01892 01893 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data); 01894 __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 01895 ast_mutex_unlock(&pkt->owner->lock); 01896 return reschedule; 01897 } 01898 /* Too many retries */ 01899 if (pkt->owner && pkt->method != SIP_OPTIONS) { 01900 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 01901 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"); 01902 } else { 01903 if ((pkt->method == SIP_OPTIONS) && sipdebug) 01904 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->owner->callid); 01905 } 01906 append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01907 01908 pkt->retransid = -1; 01909 01910 if (ast_test_flag(pkt, FLAG_FATAL)) { 01911 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 01912 ast_mutex_unlock(&pkt->owner->lock); /* SIP_PVT, not channel */ 01913 usleep(1); 01914 ast_mutex_lock(&pkt->owner->lock); 01915 } 01916 if (pkt->owner->owner) { 01917 sip_alreadygone(pkt->owner); 01918 ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pkt->owner->callid); 01919 ast_queue_hangup(pkt->owner->owner); 01920 ast_channel_unlock(pkt->owner->owner); 01921 } else { 01922 /* If no channel owner, destroy now */ 01923 01924 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 01925 if (pkt->method != SIP_OPTIONS) 01926 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 01927 } 01928 } 01929 /* In any case, go ahead and remove the packet */ 01930 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 01931 if (cur == pkt) 01932 break; 01933 } 01934 if (cur) { 01935 if (prev) 01936 prev->next = cur->next; 01937 else 01938 pkt->owner->packets = cur->next; 01939 ast_mutex_unlock(&pkt->owner->lock); 01940 free(cur); 01941 pkt = NULL; 01942 } else 01943 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 01944 if (pkt) 01945 ast_mutex_unlock(&pkt->owner->lock); 01946 return 0; 01947 }
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 2186 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, and cfsip_methods::text.
02187 { 02188 int res; 02189 02190 add_blank(req); 02191 if (sip_debug_test_pvt(p)) { 02192 if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)) 02193 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); 02194 else 02195 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); 02196 } 02197 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02198 struct sip_request tmp; 02199 parse_copy(&tmp, req); 02200 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 02201 } 02202 res = (reliable) ? 02203 __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable > 1), req->method) : 02204 __sip_xmit(p, req->data, req->len); 02205 return res; 02206 }
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 2158 of file chan_sip.c.
References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, sip_pvt::flags, get_header(), sip_request::len, sip_request::method, parse_copy(), sip_debug_test_pvt(), sip_methods, sip_nat_mode(), SIP_NO_HISTORY, sip_real_dst(), SIP_RESPONSE, SIP_UNKNOWN, cfsip_methods::text, and XMIT_CRITICAL.
02159 { 02160 int res; 02161 02162 add_blank(req); 02163 if (sip_debug_test_pvt(p)) { 02164 const struct sockaddr_in *dst = sip_real_dst(p); 02165 02166 ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n", 02167 reliable ? "Reliably " : "", sip_nat_mode(p), 02168 ast_inet_ntoa(dst->sin_addr), 02169 ntohs(dst->sin_port), req->data); 02170 } 02171 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02172 struct sip_request tmp; 02173 parse_copy(&tmp, req); 02174 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 02175 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text); 02176 } 02177 res = (reliable) ? 02178 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02179 __sip_xmit(p, req->data, req->len); 02180 if (res > 0) 02181 return 0; 02182 return res; 02183 }
static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 7703 of file chan_sip.c.
References ahp, 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().
07704 { 07705 struct hostent *hp; 07706 struct ast_hostent ahp; 07707 int port; 07708 char *c, *host, *pt; 07709 char *contact; 07710 07711 07712 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 07713 /* NAT: Don't trust the contact field. Just use what they came to us 07714 with. */ 07715 pvt->sa = pvt->recv; 07716 return 0; 07717 } 07718 07719 07720 /* Work on a copy */ 07721 contact = ast_strdupa(pvt->fullcontact); 07722 07723 /* XXX this code is repeated all over */ 07724 /* Make sure it's a SIP URL */ 07725 if (strncasecmp(contact, "sip:", 4)) { 07726 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 07727 } else 07728 contact += 4; 07729 07730 /* Ditch arguments */ 07731 /* XXX this code is replicated also shortly below */ 07732 contact = strsep(&contact, ";"); /* trim ; and beyond */ 07733 07734 /* Grab host */ 07735 host = strchr(contact, '@'); 07736 if (!host) { /* No username part */ 07737 host = contact; 07738 c = NULL; 07739 } else { 07740 *host++ = '\0'; 07741 } 07742 pt = strchr(host, ':'); 07743 if (pt) { 07744 *pt++ = '\0'; 07745 port = atoi(pt); 07746 } else 07747 port = STANDARD_SIP_PORT; 07748 07749 /* XXX This could block for a long time XXX */ 07750 /* We should only do this if it's a name, not an IP */ 07751 hp = ast_gethostbyname(host, &ahp); 07752 if (!hp) { 07753 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 07754 return -1; 07755 } 07756 pvt->sa.sin_family = AF_INET; 07757 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 07758 pvt->sa.sin_port = htons(port); 07759 07760 return 0; 07761 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
Set destination from SIP URI.
Definition at line 5495 of file chan_sip.c.
References ahp, 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().
05496 { 05497 char *h, *maddr, hostname[256]; 05498 int port, hn; 05499 struct hostent *hp; 05500 struct ast_hostent ahp; 05501 int debug=sip_debug_test_pvt(p); 05502 05503 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 05504 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 05505 05506 if (debug) 05507 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 05508 05509 /* Find and parse hostname */ 05510 h = strchr(uri, '@'); 05511 if (h) 05512 ++h; 05513 else { 05514 h = uri; 05515 if (strncmp(h, "sip:", 4) == 0) 05516 h += 4; 05517 else if (strncmp(h, "sips:", 5) == 0) 05518 h += 5; 05519 } 05520 hn = strcspn(h, ":;>") + 1; 05521 if (hn > sizeof(hostname)) 05522 hn = sizeof(hostname); 05523 ast_copy_string(hostname, h, hn); 05524 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 05525 h += hn - 1; 05526 05527 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 05528 if (*h == ':') { 05529 /* Parse port */ 05530 ++h; 05531 port = strtol(h, &h, 10); 05532 } 05533 else 05534 port = STANDARD_SIP_PORT; 05535 05536 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 05537 maddr = strstr(h, "maddr="); 05538 if (maddr) { 05539 maddr += 6; 05540 hn = strspn(maddr, "0123456789.") + 1; 05541 if (hn > sizeof(hostname)) 05542 hn = sizeof(hostname); 05543 ast_copy_string(hostname, maddr, hn); 05544 } 05545 05546 hp = ast_gethostbyname(hostname, &ahp); 05547 if (hp == NULL) { 05548 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 05549 return; 05550 } 05551 p->sa.sin_family = AF_INET; 05552 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 05553 p->sa.sin_port = htons(port); 05554 if (debug) 05555 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 05556 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 15889 of file chan_sip.c.
References sip_peer::addr, sip_peer::allowtransfer, ast_copy_flags, sip_peer::autoframing, sip_peer::callgroup, sip_peer::capability, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, default_prefs, sip_peer::expire, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, global_flags, sip_peer::language, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, sip_peer::pickupgroup, sip_peer::pokeexpire, sip_peer::prefs, sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sip_peer::secret, SIP_FLAGS_TO_COPY, SIP_PAGE2_FLAGS_TO_COPY, STANDARD_SIP_PORT, sip_peer::subscribecontext, and sip_peer::vmexten.
Referenced by build_peer(), and temp_peer().
15890 { 15891 if (peer->expire == 0) { 15892 /* Don't reset expire or port time during reload 15893 if we have an active registration 15894 */ 15895 peer->expire = -1; 15896 peer->pokeexpire = -1; 15897 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 15898 } 15899 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 15900 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 15901 strcpy(peer->context, default_context); 15902 strcpy(peer->subscribecontext, default_subscribecontext); 15903 strcpy(peer->language, default_language); 15904 strcpy(peer->mohinterpret, default_mohinterpret); 15905 strcpy(peer->mohsuggest, default_mohsuggest); 15906 peer->addr.sin_family = AF_INET; 15907 peer->defaddr.sin_family = AF_INET; 15908 peer->capability = global_capability; 15909 peer->maxcallbitrate = default_maxcallbitrate; 15910 peer->rtptimeout = global_rtptimeout; 15911 peer->rtpholdtimeout = global_rtpholdtimeout; 15912 peer->rtpkeepalive = global_rtpkeepalive; 15913 peer->allowtransfer = global_allowtransfer; 15914 peer->autoframing = global_autoframing; 15915 strcpy(peer->vmexten, default_vmexten); 15916 peer->secret[0] = '\0'; 15917 peer->md5secret[0] = '\0'; 15918 peer->cid_num[0] = '\0'; 15919 peer->cid_name[0] = '\0'; 15920 peer->fromdomain[0] = '\0'; 15921 peer->fromuser[0] = '\0'; 15922 peer->regexten[0] = '\0'; 15923 peer->mailbox[0] = '\0'; 15924 peer->callgroup = 0; 15925 peer->pickupgroup = 0; 15926 peer->maxms = default_qualify; 15927 peer->prefs = default_prefs; 15928 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 17083 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().
17084 { 17085 int no = 0; 17086 int ok = FALSE; 17087 char varbuf[30]; 17088 char *inbuf = (char *) data; 17089 17090 if (ast_strlen_zero(inbuf)) { 17091 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 17092 return 0; 17093 } 17094 ast_channel_lock(chan); 17095 17096 /* Check for headers */ 17097 while (!ok && no <= 50) { 17098 no++; 17099 snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%.2d", no); 17100 17101 /* Compare without the leading underscore */ 17102 if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 1) == (const char *) NULL) ) 17103 ok = TRUE; 17104 } 17105 if (ok) { 17106 pbx_builtin_setvar_helper (chan, varbuf, inbuf); 17107 if (sipdebug) 17108 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf); 17109 } else { 17110 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 17111 } 17112 ast_channel_unlock(chan); 17113 return 0; 17114 }
static int sip_addrcmp | ( | char * | name, | |
struct sockaddr_in * | sin | |||
) | [static] |
Support routine for find_peer.
Definition at line 2471 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, inaddrcmp(), and SIP_INSECURE_PORT.
Referenced by find_peer().
02472 { 02473 /* We know name is the first field, so we can cast */ 02474 struct sip_peer *p = (struct sip_peer *) name; 02475 return !(!inaddrcmp(&p->addr, sin) || 02476 (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) && 02477 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 02478 }
static struct sip_pvt * sip_alloc | ( | ast_string_field | callid, | |
struct sockaddr_in * | sin, | |||
int | useglobal_nat, | |||
const int | intended_method | |||
) | [static] |
Allocate SIP_PVT structure and set defaults.
Definition at line 4203 of file chan_sip.c.
References __ourip, ast_calloc, ast_copy_flags, ast_log(), ast_mutex_destroy(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), AST_RTP_DTMF, ast_rtp_new_with_bindaddr(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_settos(), ast_set2_flag, ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_set, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_new_with_bindaddr(), ast_udptl_settos(), ast_variables_destroy(), bindaddr, build_callid_pvt(), build_via(), context, default_prefs, do_setnat(), free, global_flags, global_t38_capability, iflist, INITIAL_CSEQ, io, LOG_DEBUG, LOG_WARNING, make_our_tag(), mohinterpret, mohsuggest, NONE, option_debug, sched, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, SIP_OPTIONS, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_REGISTER, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, text, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.
Referenced by sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
04205 { 04206 struct sip_pvt *p; 04207 04208 if (!(p = ast_calloc(1, sizeof(*p)))) 04209 return NULL; 04210 04211 if (ast_string_field_init(p, 512)) { 04212 free(p); 04213 return NULL; 04214 } 04215 04216 ast_mutex_init(&p->lock); 04217 04218 p->method = intended_method; 04219 p->initid = -1; 04220 p->autokillid = -1; 04221 p->subscribed = NONE; 04222 p->stateid = -1; 04223 p->prefs = default_prefs; /* Set default codecs for this call */ 04224 04225 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 04226 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 04227 04228 if (sin) { 04229 p->sa = *sin; 04230 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 04231 p->ourip = __ourip; 04232 } else 04233 p->ourip = __ourip; 04234 04235 /* Copy global flags to this PVT at setup. */ 04236 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 04237 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 04238 04239 ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY); 04240 04241 p->branch = ast_random(); 04242 make_our_tag(p->tag, sizeof(p->tag)); 04243 p->ocseq = INITIAL_CSEQ; 04244 04245 if (sip_methods[intended_method].need_rtp) { 04246 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04247 /* If the global videosupport flag is on, we always create a RTP interface for video */ 04248 if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 04249 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04250 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) 04251 p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 04252 if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) { 04253 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", 04254 ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno)); 04255 ast_mutex_destroy(&p->lock); 04256 if (p->chanvars) { 04257 ast_variables_destroy(p->chanvars); 04258 p->chanvars = NULL; 04259 } 04260 free(p); 04261 return NULL; 04262 } 04263 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04264 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04265 ast_rtp_settos(p->rtp, global_tos_audio); 04266 ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); 04267 ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); 04268 ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); 04269 if (p->vrtp) { 04270 ast_rtp_settos(p->vrtp, global_tos_video); 04271 ast_rtp_setdtmf(p->vrtp, 0); 04272 ast_rtp_setdtmfcompensate(p->vrtp, 0); 04273 ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); 04274 ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout); 04275 ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); 04276 } 04277 if (p->udptl) 04278 ast_udptl_settos(p->udptl, global_tos_audio); 04279 p->maxcallbitrate = default_maxcallbitrate; 04280 } 04281 04282 if (useglobal_nat && sin) { 04283 /* Setup NAT structure according to global settings if we have an address */ 04284 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 04285 p->recv = *sin; 04286 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04287 } 04288 04289 if (p->method != SIP_REGISTER) 04290 ast_string_field_set(p, fromdomain, default_fromdomain); 04291 build_via(p); 04292 if (!callid) 04293 build_callid_pvt(p); 04294 else 04295 ast_string_field_set(p, callid, callid); 04296 /* Assign default music on hold class */ 04297 ast_string_field_set(p, mohinterpret, default_mohinterpret); 04298 ast_string_field_set(p, mohsuggest, default_mohsuggest); 04299 p->capability = global_capability; 04300 p->allowtransfer = global_allowtransfer; 04301 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 04302 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 04303 p->noncodeccapability |= AST_RTP_DTMF; 04304 if (p->udptl) { 04305 p->t38.capability = global_t38_capability; 04306 if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY) 04307 p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 04308 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC) 04309 p->t38.capability |= T38FAX_UDP_EC_FEC; 04310 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE) 04311 p->t38.capability |= T38FAX_UDP_EC_NONE; 04312 p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 04313 p->t38.jointcapability = p->t38.capability; 04314 } 04315 ast_string_field_set(p, context, default_context); 04316 04317 /* Add to active dialog list */ 04318 ast_mutex_lock(&iflock); 04319 p->next = iflist; 04320 iflist = p; 04321 ast_mutex_unlock(&iflock); 04322 if (option_debug) 04323 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"); 04324 return p; 04325 }
static void sip_alreadygone | ( | struct sip_pvt * | dialog | ) | [static] |
Definition at line 1632 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().
01633 { 01634 if (option_debug > 2) 01635 ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 01636 ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE); 01637 }
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 3454 of file chan_sip.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_UP, sip_pvt::lock, LOG_DEBUG, option_debug, T38_ENABLED, T38_PEER_DIRECT, ast_channel::tech_pvt, transmit_response_with_sdp(), transmit_response_with_t38_sdp(), try_suggested_sip_codec(), and XMIT_CRITICAL.
03455 { 03456 int res = 0; 03457 struct sip_pvt *p = ast->tech_pvt; 03458 03459 ast_mutex_lock(&p->lock); 03460 if (ast->_state != AST_STATE_UP) { 03461 try_suggested_sip_codec(p); 03462 03463 ast_setstate(ast, AST_STATE_UP); 03464 if (option_debug) 03465 ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name); 03466 if (p->t38.state == T38_PEER_DIRECT) { 03467 p->t38.state = T38_ENABLED; 03468 if (option_debug > 1) 03469 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 03470 res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03471 } else 03472 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03473 } 03474 ast_mutex_unlock(&p->lock); 03475 return res; 03476 }
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 2772 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, sched, SIP_INVITE, SIP_OUTGOING, SIP_TRANS_TIMEOUT, sipdebug, t38properties::state, sip_pvt::t38, T38_LOCAL_DIRECT, ast_channel::tech_pvt, sip_invite_param::transfer, transmit_invite(), update_call_counter(), sip_invite_param::uri_options, ast_channel::varshead, and sip_invite_param::vxml_url.
02773 { 02774 int res; 02775 struct sip_pvt *p; 02776 struct varshead *headp; 02777 struct ast_var_t *current; 02778 const char *referer = NULL; /* SIP refererer */ 02779 02780 p = ast->tech_pvt; 02781 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 02782 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 02783 return -1; 02784 } 02785 02786 /* Check whether there is vxml_url, distinctive ring variables */ 02787 headp=&ast->varshead; 02788 AST_LIST_TRAVERSE(headp,current,entries) { 02789 /* Check whether there is a VXML_URL variable */ 02790 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 02791 p->options->vxml_url = ast_var_value(current); 02792 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 02793 p->options->uri_options = ast_var_value(current); 02794 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 02795 /* Check whether there is a ALERT_INFO variable */ 02796 p->options->distinctive_ring = ast_var_value(current); 02797 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 02798 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 02799 p->options->addsipheaders = 1; 02800 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 02801 /* This is a transfered call */ 02802 p->options->transfer = 1; 02803 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 02804 /* This is the referer */ 02805 referer = ast_var_value(current); 02806 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 02807 /* We're replacing a call. */ 02808 p->options->replaces = ast_var_value(current); 02809 } else if (!strcasecmp(ast_var_name(current), "T38CALL")) { 02810 p->t38.state = T38_LOCAL_DIRECT; 02811 if (option_debug) 02812 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 02813 } 02814 02815 } 02816 02817 res = 0; 02818 ast_set_flag(&p->flags[0], SIP_OUTGOING); 02819 02820 if (p->options->transfer) { 02821 char buf[BUFSIZ/2]; 02822 02823 if (referer) { 02824 if (sipdebug && option_debug > 2) 02825 ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer); 02826 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 02827 } else 02828 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 02829 ast_string_field_set(p, cid_name, buf); 02830 } 02831 if (option_debug) 02832 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 02833 02834 res = update_call_counter(p, INC_CALL_RINGING); 02835 if ( res != -1 ) { 02836 p->callingpres = ast->cid.cid_pres; 02837 p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec); 02838 p->jointnoncodeccapability = p->noncodeccapability; 02839 02840 /* If there are no audio formats left to offer, punt */ 02841 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 02842 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 02843 res = -1; 02844 } else { 02845 p->t38.jointcapability = p->t38.capability; 02846 if (option_debug > 1) 02847 ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability); 02848 transmit_invite(p, SIP_INVITE, 1, 2); 02849 p->invitestate = INV_CALLING; 02850 02851 /* Initialize auto-congest time */ 02852 p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p); 02853 } 02854 } 02855 return res; 02856 }
static void sip_cancel_destroy | ( | struct sip_pvt * | p | ) | [static] |
Cancel destruction of SIP dialog.
Definition at line 2046 of file chan_sip.c.
References append_history, ast_sched_del(), sip_pvt::autokillid, and sched.
Referenced by cb_extensionstate(), check_user_full(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), and sip_hangup().
02047 { 02048 if (p->autokillid > -1) { 02049 ast_sched_del(sched, p->autokillid); 02050 append_history(p, "CancelDestroy", ""); 02051 p->autokillid = -1; 02052 } 02053 }
static int sip_debug_test_addr | ( | const struct sockaddr_in * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 1714 of file chan_sip.c.
References sipdebug.
Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().
01715 { 01716 if (!sipdebug) 01717 return 0; 01718 if (debugaddr.sin_addr.s_addr) { 01719 if (((ntohs(debugaddr.sin_port) != 0) 01720 && (debugaddr.sin_port != addr->sin_port)) 01721 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01722 return 0; 01723 } 01724 return 1; 01725 }
static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 1740 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().
01741 { 01742 if (!sipdebug) 01743 return 0; 01744 return sip_debug_test_addr(sip_real_dst(p)); 01745 }
static void sip_destroy | ( | struct sip_pvt * | p | ) | [static] |
Destroy SIP call structure.
Definition at line 3107 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().
03108 { 03109 ast_mutex_lock(&iflock); 03110 if (option_debug > 2) 03111 ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid); 03112 __sip_destroy(p, 1); 03113 ast_mutex_unlock(&iflock); 03114 }
static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 2358 of file chan_sip.c.
References ast_free_ha(), ast_log(), ast_sched_del(), ast_test_flag, ast_variables_destroy(), sip_peer::auth, sip_peer::call, sip_peer::chanvars, clear_realm_authentication(), sip_peer::expire, FALSE, sip_peer::flags, free, sip_peer::ha, LOG_DEBUG, sip_peer::mwipvt, option_debug, sip_peer::pokeexpire, register_peer_exten(), sched, sip_destroy(), SIP_PAGE2_SELFDESTRUCT, and SIP_REALTIME.
Referenced by __sip_autodestruct(), _sip_show_peer(), build_peer(), check_user_full(), create_addr(), expire_register(), function_sippeer(), handle_request_subscribe(), register_verify(), sip_devicestate(), sip_do_debug_peer(), sip_prune_realtime(), unload_module(), and update_call_counter().
02359 { 02360 if (option_debug > 2) 02361 ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name); 02362 02363 /* Delete it, it needs to disappear */ 02364 if (peer->call) 02365 sip_destroy(peer->call); 02366 02367 if (peer->mwipvt) /* We have an active subscription, delete it */ 02368 sip_destroy(peer->mwipvt); 02369 02370 if (peer->chanvars) { 02371 ast_variables_destroy(peer->chanvars); 02372 peer->chanvars = NULL; 02373 } 02374 if (peer->expire > -1) 02375 ast_sched_del(sched, peer->expire); 02376 02377 if (peer->pokeexpire > -1) 02378 ast_sched_del(sched, peer->pokeexpire); 02379 register_peer_exten(peer, FALSE); 02380 ast_free_ha(peer->ha); 02381 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT)) 02382 apeerobjs--; 02383 else if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) 02384 rpeerobjs--; 02385 else 02386 speerobjs--; 02387 clear_realm_authentication(peer->auth); 02388 peer->auth = NULL; 02389 free(peer); 02390 }
static void sip_destroy_user | ( | struct sip_user * | user | ) | [static] |
Remove user object from in-memory storage.
Definition at line 2499 of file chan_sip.c.
References ast_free_ha(), ast_log(), ast_test_flag, ast_variables_destroy(), sip_user::chanvars, sip_user::flags, free, sip_user::ha, LOG_DEBUG, option_debug, and SIP_REALTIME.
Referenced by check_user_full(), sip_show_user(), unload_module(), and update_call_counter().
02500 { 02501 if (option_debug > 2) 02502 ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name); 02503 ast_free_ha(user->ha); 02504 if (user->chanvars) { 02505 ast_variables_destroy(user->chanvars); 02506 user->chanvars = NULL; 02507 } 02508 if (ast_test_flag(&user->flags[0], SIP_REALTIME)) 02509 ruserobjs--; 02510 else 02511 suserobjs--; 02512 free(user); 02513 }
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 15327 of file chan_sip.c.
References sip_peer::addr, ahp, AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_gethostbyname(), ast_log(), ast_strdupa, ASTOBJ_UNREF, sip_peer::call_limit, sip_peer::defaddr, find_peer(), hp, sip_peer::inRinging, sip_peer::inUse, sip_peer::lastms, LOG_DEBUG, sip_peer::maxms, sip_peer::onHold, option_debug, and sip_destroy_peer().
15328 { 15329 char *host; 15330 char *tmp; 15331 15332 struct hostent *hp; 15333 struct ast_hostent ahp; 15334 struct sip_peer *p; 15335 15336 int res = AST_DEVICE_INVALID; 15337 15338 /* make sure data is not null. Maybe unnecessary, but better be safe */ 15339 host = ast_strdupa(data ? data : ""); 15340 if ((tmp = strchr(host, '@'))) 15341 host = tmp + 1; 15342 15343 if (option_debug > 2) 15344 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 15345 15346 if ((p = find_peer(host, NULL, 1))) { 15347 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 15348 /* we have an address for the peer */ 15349 15350 /* Check status in this order 15351 - Hold 15352 - Ringing 15353 - Busy (enforced only by call limit) 15354 - Inuse (we have a call) 15355 - Unreachable (qualify) 15356 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 15357 for registered devices */ 15358 15359 if (p->onHold) 15360 /* First check for hold or ring states */ 15361 res = AST_DEVICE_ONHOLD; 15362 else if (p->inRinging) { 15363 if (p->inRinging == p->inUse) 15364 res = AST_DEVICE_RINGING; 15365 else 15366 res = AST_DEVICE_RINGINUSE; 15367 } else if (p->call_limit && (p->inUse == p->call_limit)) 15368 /* check call limit */ 15369 res = AST_DEVICE_BUSY; 15370 else if (p->call_limit && p->inUse) 15371 /* Not busy, but we do have a call */ 15372 res = AST_DEVICE_INUSE; 15373 else if (p->maxms && (p->lastms > p->maxms)) 15374 /* We don't have a call. Are we reachable at all? Requires qualify= */ 15375 res = AST_DEVICE_UNAVAILABLE; 15376 else /* Default reply if we're registered and have no other data */ 15377 res = AST_DEVICE_NOT_INUSE; 15378 } else { 15379 /* there is no address, it's unavailable */ 15380 res = AST_DEVICE_UNAVAILABLE; 15381 } 15382 ASTOBJ_UNREF(p,sip_destroy_peer); 15383 } else { 15384 hp = ast_gethostbyname(host, &ahp); 15385 if (hp) 15386 res = AST_DEVICE_UNKNOWN; 15387 } 15388 15389 return res; 15390 }
static int sip_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 10931 of file chan_sip.c.
References ast_cli(), ast_set_flag, debugaddr, global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_do_debug_ip(), sip_do_debug_peer(), SIP_PAGE2_DEBUG_CONSOLE, and sipdebug_console.
10932 { 10933 int oldsipdebug = sipdebug_console; 10934 if (argc != 3) { 10935 if (argc != 5) 10936 return RESULT_SHOWUSAGE; 10937 else if (strcmp(argv[3], "ip") == 0) 10938 return sip_do_debug_ip(fd, argc, argv); 10939 else if (strcmp(argv[3], "peer") == 0) 10940 return sip_do_debug_peer(fd, argc, argv); 10941 else 10942 return RESULT_SHOWUSAGE; 10943 } 10944 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 10945 memset(&debugaddr, 0, sizeof(debugaddr)); 10946 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 10947 return RESULT_SUCCESS; 10948 }
static int sip_do_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 10950 of file chan_sip.c.
References ast_cli(), ast_set_flag, debugaddr, global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_do_debug_ip(), sip_do_debug_peer(), SIP_PAGE2_DEBUG_CONSOLE, and sipdebug_console.
10951 { 10952 int oldsipdebug = sipdebug_console; 10953 char *newargv[6] = { "sip", "set", "debug", NULL }; 10954 if (argc != 2) { 10955 if (argc != 4) 10956 return RESULT_SHOWUSAGE; 10957 else if (strcmp(argv[2], "ip") == 0) { 10958 newargv[3] = argv[2]; 10959 newargv[4] = argv[3]; 10960 return sip_do_debug_ip(fd, argc + 1, newargv); 10961 } else if (strcmp(argv[2], "peer") == 0) { 10962 newargv[3] = argv[2]; 10963 newargv[4] = argv[3]; 10964 return sip_do_debug_peer(fd, argc + 1, newargv); 10965 } else 10966 return RESULT_SHOWUSAGE; 10967 } 10968 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 10969 memset(&debugaddr, 0, sizeof(debugaddr)); 10970 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 10971 return RESULT_SUCCESS; 10972 }
static int sip_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP Debugging in CLI.
Definition at line 10877 of file chan_sip.c.
References ahp, ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), ast_set_flag, debugaddr, global_flags, hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_PAGE2_DEBUG_CONSOLE, and strsep().
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
10878 { 10879 struct hostent *hp; 10880 struct ast_hostent ahp; 10881 int port = 0; 10882 char *p, *arg; 10883 10884 /* sip set debug ip <ip> */ 10885 if (argc != 5) 10886 return RESULT_SHOWUSAGE; 10887 p = arg = argv[4]; 10888 strsep(&p, ":"); 10889 if (p) 10890 port = atoi(p); 10891 hp = ast_gethostbyname(arg, &ahp); 10892 if (hp == NULL) 10893 return RESULT_SHOWUSAGE; 10894 10895 debugaddr.sin_family = AF_INET; 10896 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 10897 debugaddr.sin_port = htons(port); 10898 if (port == 0) 10899 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 10900 else 10901 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 10902 10903 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 10904 10905 return RESULT_SUCCESS; 10906 }
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 10909 of file chan_sip.c.
References sip_peer::addr, ast_cli(), ast_inet_ntoa(), ast_set_flag, ASTOBJ_UNREF, debugaddr, find_peer(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_destroy_peer(), and SIP_PAGE2_DEBUG_CONSOLE.
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
10910 { 10911 struct sip_peer *peer; 10912 if (argc != 5) 10913 return RESULT_SHOWUSAGE; 10914 peer = find_peer(argv[4], NULL, 1); 10915 if (peer) { 10916 if (peer->addr.sin_addr.s_addr) { 10917 debugaddr.sin_family = AF_INET; 10918 debugaddr.sin_addr = peer->addr.sin_addr; 10919 debugaddr.sin_port = peer->addr.sin_port; 10920 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 10921 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 10922 } else 10923 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]); 10924 ASTOBJ_UNREF(peer,sip_destroy_peer); 10925 } else 10926 ast_cli(fd, "No such peer '%s'\n", argv[4]); 10927 return RESULT_SUCCESS; 10928 }
static int sip_do_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP History logging (CLI).
Definition at line 11050 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and TRUE.
11051 { 11052 if (argc != 2) { 11053 return RESULT_SHOWUSAGE; 11054 } 11055 recordhistory = TRUE; 11056 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 11057 return RESULT_SUCCESS; 11058 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 17225 of file chan_sip.c.
References ast_log(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, authl, clear_realm_authentication(), clear_sip_domains(), LOG_DEBUG, regl, and sip_destroy().
Referenced by do_monitor().
17226 { 17227 if (option_debug > 3) 17228 ast_log(LOG_DEBUG, "--------------- SIP reload started\n"); 17229 17230 clear_realm_authentication(authl); 17231 clear_sip_domains(); 17232 authl = NULL; 17233 17234 /* First, destroy all outstanding registry calls */ 17235 /* This is needed, since otherwise active registry entries will not be destroyed */ 17236 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17237 ASTOBJ_RDLOCK(iterator); 17238 if (iterator->call) { 17239 if (option_debug > 2) 17240 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 17241 /* This will also remove references to the registry */ 17242 sip_destroy(iterator->call); 17243 } 17244 ASTOBJ_UNLOCK(iterator); 17245 17246 } while(0)); 17247 17248 /* Then, actually destroy users and registry */ 17249 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 17250 if (option_debug > 3) 17251 ast_log(LOG_DEBUG, "--------------- Done destroying user list\n"); 17252 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 17253 if (option_debug > 3) 17254 ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n"); 17255 ASTOBJ_CONTAINER_MARKALL(&peerl); 17256 reload_config(reason); 17257 17258 /* Prune peers who still are supposed to be deleted */ 17259 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 17260 if (option_debug > 3) 17261 ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n"); 17262 17263 /* Send qualify (OPTIONS) to all peers */ 17264 sip_poke_all_peers(); 17265 17266 /* Register with all services */ 17267 sip_send_all_registers(); 17268 17269 if (option_debug > 3) 17270 ast_log(LOG_DEBUG, "--------------- SIP reload done\n"); 17271 17272 return 0; 17273 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 17028 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().
17029 { 17030 struct sip_pvt *p; 17031 char *mode; 17032 if (data) 17033 mode = (char *)data; 17034 else { 17035 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 17036 return 0; 17037 } 17038 ast_channel_lock(chan); 17039 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 17040 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 17041 ast_channel_unlock(chan); 17042 return 0; 17043 } 17044 p = chan->tech_pvt; 17045 if (!p) { 17046 ast_channel_unlock(chan); 17047 return 0; 17048 } 17049 ast_mutex_lock(&p->lock); 17050 if (!strcasecmp(mode,"info")) { 17051 ast_clear_flag(&p->flags[0], SIP_DTMF); 17052 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 17053 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 17054 } else if (!strcasecmp(mode,"rfc2833")) { 17055 ast_clear_flag(&p->flags[0], SIP_DTMF); 17056 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 17057 p->jointnoncodeccapability |= AST_RTP_DTMF; 17058 } else if (!strcasecmp(mode,"inband")) { 17059 ast_clear_flag(&p->flags[0], SIP_DTMF); 17060 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 17061 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 17062 } else 17063 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 17064 if (p->rtp) 17065 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 17066 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 17067 if (!p->vad) { 17068 p->vad = ast_dsp_new(); 17069 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 17070 } 17071 } else { 17072 if (p->vad) { 17073 ast_dsp_free(p->vad); 17074 p->vad = NULL; 17075 } 17076 } 17077 ast_mutex_unlock(&p->lock); 17078 ast_channel_unlock(chan); 17079 return 0; 17080 }
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 10747 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().
10748 { 10749 int x = 0; 10750 struct sip_history *hist; 10751 static int errmsg = 0; 10752 10753 if (!dialog) 10754 return; 10755 10756 if (!option_debug && !sipdebug) { 10757 if (!errmsg) { 10758 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 10759 errmsg = 1; 10760 } 10761 return; 10762 } 10763 10764 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 10765 if (dialog->subscribed) 10766 ast_log(LOG_DEBUG, " * Subscription\n"); 10767 else 10768 ast_log(LOG_DEBUG, " * SIP Call\n"); 10769 if (dialog->history) 10770 AST_LIST_TRAVERSE(dialog->history, hist, list) 10771 ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); 10772 if (!x) 10773 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 10774 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 10775 }
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 3558 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.
03559 { 03560 int ret = -1; 03561 struct sip_pvt *p; 03562 03563 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug) 03564 ast_log(LOG_DEBUG, "New channel is zombie\n"); 03565 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug) 03566 ast_log(LOG_DEBUG, "Old channel is zombie\n"); 03567 03568 if (!newchan || !newchan->tech_pvt) { 03569 if (!newchan) 03570 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 03571 else 03572 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 03573 return -1; 03574 } 03575 p = newchan->tech_pvt; 03576 03577 if (!p) { 03578 ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n"); 03579 return -1; 03580 } 03581 03582 ast_mutex_lock(&p->lock); 03583 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 03584 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 03585 if (p->owner != oldchan) 03586 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 03587 else { 03588 p->owner = newchan; 03589 ret = 0; 03590 } 03591 if (option_debug > 2) 03592 ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 03593 03594 ast_mutex_unlock(&p->lock); 03595 return ret; 03596 }
static int sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Return SIP UA's codec (part of the RTP interface).
Definition at line 17174 of file chan_sip.c.
References sip_pvt::capability, sip_pvt::peercapability, and ast_channel::tech_pvt.
17175 { 17176 struct sip_pvt *p = chan->tech_pvt; 17177 return p->peercapability ? p->peercapability : p->capability; 17178 }
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 16888 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.
16889 { 16890 struct sip_pvt *p = NULL; 16891 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 16892 16893 if (!(p = chan->tech_pvt)) 16894 return AST_RTP_GET_FAILED; 16895 16896 ast_mutex_lock(&p->lock); 16897 if (!(p->rtp)) { 16898 ast_mutex_unlock(&p->lock); 16899 return AST_RTP_GET_FAILED; 16900 } 16901 16902 *rtp = p->rtp; 16903 16904 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 16905 res = AST_RTP_TRY_PARTIAL; 16906 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 16907 res = AST_RTP_TRY_NATIVE; 16908 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 16909 res = AST_RTP_GET_FAILED; 16910 16911 ast_mutex_unlock(&p->lock); 16912 16913 return res; 16914 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 16753 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.
16754 { 16755 struct sip_pvt *p; 16756 struct ast_udptl *udptl = NULL; 16757 16758 p = chan->tech_pvt; 16759 if (!p) 16760 return NULL; 16761 16762 ast_mutex_lock(&p->lock); 16763 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 16764 udptl = p->udptl; 16765 ast_mutex_unlock(&p->lock); 16766 return udptl; 16767 }
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 16917 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_GET_FAILED, AST_RTP_TRY_NATIVE, AST_RTP_TRY_PARTIAL, ast_test_flag, sip_pvt::flags, sip_pvt::lock, sip_pvt::rtp, SIP_CAN_REINVITE, ast_channel::tech_pvt, and sip_pvt::vrtp.
16918 { 16919 struct sip_pvt *p = NULL; 16920 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 16921 16922 if (!(p = chan->tech_pvt)) 16923 return AST_RTP_GET_FAILED; 16924 16925 ast_mutex_lock(&p->lock); 16926 if (!(p->vrtp)) { 16927 ast_mutex_unlock(&p->lock); 16928 return AST_RTP_GET_FAILED; 16929 } 16930 16931 *rtp = p->vrtp; 16932 16933 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 16934 res = AST_RTP_TRY_NATIVE; 16935 16936 ast_mutex_unlock(&p->lock); 16937 16938 return res; 16939 }
static int sip_handle_t38_reinvite | ( | struct ast_channel * | chan, | |
struct sip_pvt * | pvt, | |||
int | reinvite | |||
) | [static] |
Handle T38 reinvite.
Definition at line 16805 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_get_local_max_datagram(), ast_udptl_get_peer(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_local_max_datagram(), sip_pvt::flags, sip_pvt::initreq, t38properties::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, sip_pvt::ourip, sip_pvt::owner, t38properties::peercapability, sip_pvt::pendinginvite, SIP_CAN_REINVITE, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, t38properties::state, sip_pvt::t38, T38_ENABLED, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), transmit_response_with_t38_sdp(), sip_pvt::udptl, sip_pvt::udptlredirip, and XMIT_CRITICAL.
Referenced by handle_request_invite(), and handle_response_invite().
16806 { 16807 struct sip_pvt *p; 16808 int flag = 0; 16809 16810 p = chan->tech_pvt; 16811 if (!p || !pvt->udptl) 16812 return -1; 16813 16814 /* Setup everything on the other side like offered/responded from first side */ 16815 ast_mutex_lock(&p->lock); 16816 16817 /*! \todo check if this is not set earlier when setting up the PVT. If not 16818 maybe it should move there. */ 16819 p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability; 16820 16821 ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 16822 ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 16823 ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl)); 16824 16825 if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */ 16826 /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects, 16827 not really T38 re-invites which are different. In this 16828 case it's used properly, to see if we can reinvite over 16829 NAT 16830 */ 16831 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 16832 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 16833 flag =1; 16834 } else { 16835 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 16836 } 16837 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 16838 if (!p->pendinginvite) { 16839 if (option_debug > 2) { 16840 if (flag) 16841 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)); 16842 else 16843 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)); 16844 } 16845 transmit_reinvite_with_t38_sdp(p); 16846 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 16847 if (option_debug > 2) { 16848 if (flag) 16849 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)); 16850 else 16851 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)); 16852 } 16853 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 16854 } 16855 } 16856 /* Reset lastrtprx timer */ 16857 p->lastrtprx = p->lastrtptx = time(NULL); 16858 ast_mutex_unlock(&p->lock); 16859 return 0; 16860 } else { /* If we are handling sending 200 OK to the other side of the bridge */ 16861 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 16862 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 16863 flag = 1; 16864 } else { 16865 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 16866 } 16867 if (option_debug > 2) { 16868 if (flag) 16869 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)); 16870 else 16871 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)); 16872 } 16873 pvt->t38.state = T38_ENABLED; 16874 p->t38.state = T38_ENABLED; 16875 if (option_debug > 1) { 16876 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 16877 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 16878 } 16879 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 16880 p->lastrtprx = p->lastrtptx = time(NULL); 16881 ast_mutex_unlock(&p->lock); 16882 return 0; 16883 } 16884 }
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 3279 of file chan_sip.c.
References __sip_pretend_ack(), ast_channel::_state, append_history, ast_clear_flag, ast_dsp_free(), AST_FLAG_ZOMBIE, ast_log(), ast_module_unref(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_quality(), ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, sip_pvt::autokillid, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, INC_CALL_LIMIT, INV_CALLING, INV_COMPLETED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_DEFER_BYE_ON_TRANSFER, SIP_INC_COUNT, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_PENDINGBYE, sip_scheddestroy(), sipdebug, ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, update_call_counter(), sip_pvt::vad, and XMIT_RELIABLE.
03280 { 03281 struct sip_pvt *p = ast->tech_pvt; 03282 int needcancel = FALSE; 03283 int needdestroy = 0; 03284 struct ast_channel *oldowner = ast; 03285 03286 if (!p) { 03287 if (option_debug) 03288 ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n"); 03289 return 0; 03290 } 03291 03292 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 03293 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT)) { 03294 if (option_debug && sipdebug) 03295 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03296 update_call_counter(p, DEC_CALL_LIMIT); 03297 } 03298 if (option_debug >3) 03299 ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 03300 if (p->autokillid > -1) 03301 sip_cancel_destroy(p); 03302 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03303 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 03304 ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY); 03305 p->owner->tech_pvt = NULL; 03306 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 03307 return 0; 03308 } 03309 if (option_debug) { 03310 if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug) 03311 ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 03312 else { 03313 if (option_debug) 03314 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 03315 } 03316 } 03317 if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 03318 ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n"); 03319 03320 ast_mutex_lock(&p->lock); 03321 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT)) { 03322 if (option_debug && sipdebug) 03323 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03324 update_call_counter(p, DEC_CALL_LIMIT); 03325 } 03326 03327 /* Determine how to disconnect */ 03328 if (p->owner != ast) { 03329 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 03330 ast_mutex_unlock(&p->lock); 03331 return 0; 03332 } 03333 /* If the call is not UP, we need to send CANCEL instead of BYE */ 03334 if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) { 03335 needcancel = TRUE; 03336 if (option_debug > 3) 03337 ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 03338 } 03339 03340 /* Disconnect */ 03341 if (p->vad) 03342 ast_dsp_free(p->vad); 03343 03344 p->owner = NULL; 03345 ast->tech_pvt = NULL; 03346 03347 ast_module_unref(ast_module_info->self); 03348 03349 /* Do not destroy this pvt until we have timeout or 03350 get an answer to the BYE or INVITE/CANCEL 03351 If we get no answer during retransmit period, drop the call anyway. 03352 (Sorry, mother-in-law, you can't deny a hangup by sending 03353 603 declined to BYE...) 03354 */ 03355 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) 03356 needdestroy = 1; /* Set destroy flag at end of this function */ 03357 else if (p->invitestate != INV_CALLING) 03358 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03359 03360 /* Start the process if it's not already started */ 03361 if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 03362 if (needcancel) { /* Outgoing call, not up */ 03363 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03364 /* stop retransmitting an INVITE that has not received a response */ 03365 __sip_pretend_ack(p); 03366 03367 /* if we can't send right now, mark it pending */ 03368 if (p->invitestate == INV_CALLING) { 03369 /* We can't send anything in CALLING state */ 03370 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03371 /* Do we need a timer here if we don't hear from them at all? */ 03372 } else { 03373 /* Send a new request: CANCEL */ 03374 transmit_request(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE); 03375 /* Actually don't destroy us yet, wait for the 487 on our original 03376 INVITE, but do set an autodestruct just in case we never get it. */ 03377 needdestroy = 0; 03378 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03379 } 03380 if ( p->initid != -1 ) { 03381 /* channel still up - reverse dec of inUse counter 03382 only if the channel is not auto-congested */ 03383 update_call_counter(p, INC_CALL_LIMIT); 03384 } 03385 } else { /* Incoming call, not up */ 03386 const char *res; 03387 if (ast->hangupcause && (res = hangup_cause2sip(ast->hangupcause))) 03388 transmit_response_reliable(p, res, &p->initreq); 03389 else 03390 transmit_response_reliable(p, "603 Declined", &p->initreq); 03391 } 03392 } else { /* Call is in UP state, send BYE */ 03393 if (!p->pendinginvite) { 03394 char *audioqos = ""; 03395 char *videoqos = ""; 03396 if (p->rtp) 03397 audioqos = ast_rtp_get_quality(p->rtp, NULL); 03398 if (p->vrtp) 03399 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 03400 /* Send a hangup */ 03401 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03402 03403 /* Get RTCP quality before end of call */ 03404 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 03405 if (p->rtp) 03406 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 03407 if (p->vrtp) 03408 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 03409 } 03410 if (p->rtp && oldowner) 03411 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); 03412 if (p->vrtp && oldowner) 03413 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos); 03414 } else { 03415 /* Note we will need a BYE when this all settles out 03416 but we can't send one while we have "INVITE" outstanding. */ 03417 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03418 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 03419 sip_cancel_destroy(p); 03420 } 03421 } 03422 } 03423 if (needdestroy) 03424 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 03425 ast_mutex_unlock(&p->lock); 03426 return 0; 03427 }
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 3667 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.
03668 { 03669 struct sip_pvt *p = ast->tech_pvt; 03670 int res = 0; 03671 03672 ast_mutex_lock(&p->lock); 03673 switch(condition) { 03674 case AST_CONTROL_RINGING: 03675 if (ast->_state == AST_STATE_RING) { 03676 p->invitestate = INV_EARLY_MEDIA; 03677 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 03678 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 03679 /* Send 180 ringing if out-of-band seems reasonable */ 03680 transmit_response(p, "180 Ringing", &p->initreq); 03681 ast_set_flag(&p->flags[0], SIP_RINGING); 03682 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 03683 break; 03684 } else { 03685 /* Well, if it's not reasonable, just send in-band */ 03686 } 03687 } 03688 res = -1; 03689 break; 03690 case AST_CONTROL_BUSY: 03691 if (ast->_state != AST_STATE_UP) { 03692 transmit_response(p, "486 Busy Here", &p->initreq); 03693 p->invitestate = INV_COMPLETED; 03694 sip_alreadygone(p); 03695 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03696 break; 03697 } 03698 res = -1; 03699 break; 03700 case AST_CONTROL_CONGESTION: 03701 if (ast->_state != AST_STATE_UP) { 03702 transmit_response(p, "503 Service Unavailable", &p->initreq); 03703 p->invitestate = INV_COMPLETED; 03704 sip_alreadygone(p); 03705 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03706 break; 03707 } 03708 res = -1; 03709 break; 03710 case AST_CONTROL_PROCEEDING: 03711 if ((ast->_state != AST_STATE_UP) && 03712 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03713 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03714 transmit_response(p, "100 Trying", &p->initreq); 03715 p->invitestate = INV_PROCEEDING; 03716 break; 03717 } 03718 res = -1; 03719 break; 03720 case AST_CONTROL_PROGRESS: 03721 if ((ast->_state != AST_STATE_UP) && 03722 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03723 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03724 p->invitestate = INV_EARLY_MEDIA; 03725 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03726 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03727 break; 03728 } 03729 res = -1; 03730 break; 03731 case AST_CONTROL_HOLD: 03732 ast_moh_start(ast, data, p->mohinterpret); 03733 break; 03734 case AST_CONTROL_UNHOLD: 03735 ast_moh_stop(ast); 03736 break; 03737 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 03738 if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 03739 transmit_info_with_vidupdate(p); 03740 /* ast_rtcp_send_h261fur(p->vrtp); */ 03741 } else 03742 res = -1; 03743 break; 03744 case -1: 03745 res = -1; 03746 break; 03747 default: 03748 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 03749 res = -1; 03750 break; 03751 } 03752 ast_mutex_unlock(&p->lock); 03753 return res; 03754 }
static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 1734 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().
01735 { 01736 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT"; 01737 }
static struct ast_channel* sip_new | ( | struct sip_pvt * | i, | |
int | state, | |||
const char * | title | |||
) | [static] |
Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels.
Definition at line 3763 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().
03764 { 03765 struct ast_channel *tmp; 03766 struct ast_variable *v = NULL; 03767 int fmt; 03768 int what; 03769 int needvideo = 0; 03770 { 03771 const char *my_name; /* pick a good name */ 03772 03773 if (title) 03774 my_name = title; 03775 else if ( (my_name = strchr(i->fromdomain,':')) ) 03776 my_name++; /* skip ':' */ 03777 else 03778 my_name = i->fromdomain; 03779 03780 ast_mutex_unlock(&i->lock); 03781 /* Don't hold a sip pvt lock while we allocate a channel */ 03782 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); 03783 03784 } 03785 if (!tmp) { 03786 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 03787 return NULL; 03788 } 03789 ast_mutex_lock(&i->lock); 03790 03791 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO) 03792 tmp->tech = &sip_tech_info; 03793 else 03794 tmp->tech = &sip_tech; 03795 03796 /* Select our native format based on codec preference until we receive 03797 something from another device to the contrary. */ 03798 if (i->jointcapability) /* The joint capabilities of us and peer */ 03799 what = i->jointcapability; 03800 else if (i->capability) /* Our configured capability for this peer */ 03801 what = i->capability; 03802 else 03803 what = global_capability; /* Global codec support */ 03804 03805 /* Set the native formats for audio and merge in video */ 03806 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | (i->jointcapability & AST_FORMAT_VIDEO_MASK); 03807 if (option_debug > 2) { 03808 char buf[BUFSIZ]; 03809 ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, BUFSIZ, tmp->nativeformats)); 03810 ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->jointcapability)); 03811 ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->capability)); 03812 ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, BUFSIZ, ast_codec_choose(&i->prefs, what, 1))); 03813 if (i->prefcodec) 03814 ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->prefcodec)); 03815 } 03816 03817 /* XXX Why are we choosing a codec from the native formats?? */ 03818 fmt = ast_best_codec(tmp->nativeformats); 03819 03820 /* If we have a prefcodec setting, we have an inbound channel that set a 03821 preferred format for this call. Otherwise, we check the jointcapability 03822 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 03823 */ 03824 if (i->vrtp) { 03825 if (i->prefcodec) 03826 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 03827 else 03828 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 03829 } 03830 03831 if (option_debug > 2) { 03832 if (needvideo) 03833 ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n"); 03834 else 03835 ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n"); 03836 } 03837 03838 03839 03840 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 03841 i->vad = ast_dsp_new(); 03842 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 03843 if (global_relaxdtmf) 03844 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 03845 } 03846 if (i->rtp) { 03847 tmp->fds[0] = ast_rtp_fd(i->rtp); 03848 tmp->fds[1] = ast_rtcp_fd(i->rtp); 03849 } 03850 if (needvideo && i->vrtp) { 03851 tmp->fds[2] = ast_rtp_fd(i->vrtp); 03852 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 03853 } 03854 if (i->udptl) { 03855 tmp->fds[5] = ast_udptl_fd(i->udptl); 03856 } 03857 if (state == AST_STATE_RING) 03858 tmp->rings = 1; 03859 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 03860 tmp->writeformat = fmt; 03861 tmp->rawwriteformat = fmt; 03862 tmp->readformat = fmt; 03863 tmp->rawreadformat = fmt; 03864 tmp->tech_pvt = i; 03865 03866 tmp->callgroup = i->callgroup; 03867 tmp->pickupgroup = i->pickupgroup; 03868 tmp->cid.cid_pres = i->callingpres; 03869 if (!ast_strlen_zero(i->accountcode)) 03870 ast_string_field_set(tmp, accountcode, i->accountcode); 03871 if (i->amaflags) 03872 tmp->amaflags = i->amaflags; 03873 if (!ast_strlen_zero(i->language)) 03874 ast_string_field_set(tmp, language, i->language); 03875 i->owner = tmp; 03876 ast_module_ref(ast_module_info->self); 03877 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 03878 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 03879 03880 03881 /* Don't use ast_set_callerid() here because it will 03882 * generate an unnecessary NewCallerID event */ 03883 tmp->cid.cid_num = ast_strdup(i->cid_num); 03884 tmp->cid.cid_ani = ast_strdup(i->cid_num); 03885 tmp->cid.cid_name = ast_strdup(i->cid_name); 03886 if (!ast_strlen_zero(i->rdnis)) 03887 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 03888 03889 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 03890 tmp->cid.cid_dnid = ast_strdup(i->exten); 03891 03892 tmp->priority = 1; 03893 if (!ast_strlen_zero(i->uri)) 03894 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 03895 if (!ast_strlen_zero(i->domain)) 03896 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 03897 if (!ast_strlen_zero(i->useragent)) 03898 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 03899 if (!ast_strlen_zero(i->callid)) 03900 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 03901 if (i->rtp) 03902 ast_jb_configure(tmp, &global_jbconf); 03903 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 03904 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 03905 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 03906 ast_hangup(tmp); 03907 tmp = NULL; 03908 } 03909 /* Set channel variables for this call from configuration */ 03910 for (v = i->chanvars ; v ; v = v->next) 03911 pbx_builtin_setvar_helper(tmp,v->name,v->value); 03912 03913 if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY)) 03914 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 03915 03916 return tmp; 03917 }
static int sip_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP Debugging in CLI.
Definition at line 11031 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11032 { 11033 if (argc != 4) 11034 return RESULT_SHOWUSAGE; 11035 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11036 ast_cli(fd, "SIP Debugging Disabled\n"); 11037 return RESULT_SUCCESS; 11038 }
static int sip_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11040 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11041 { 11042 if (argc != 3) 11043 return RESULT_SHOWUSAGE; 11044 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11045 ast_cli(fd, "SIP Debugging Disabled\n"); 11046 return RESULT_SUCCESS; 11047 }
static int sip_no_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP History logging (CLI).
Definition at line 11061 of file chan_sip.c.
References ast_cli(), FALSE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
11062 { 11063 if (argc != 3) { 11064 return RESULT_SHOWUSAGE; 11065 } 11066 recordhistory = FALSE; 11067 ast_cli(fd, "SIP History Recording Disabled\n"); 11068 return RESULT_SUCCESS; 11069 }
static int sip_notify | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Cli command to send SIP notify to peer.
Definition at line 10975 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, notify_types, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), and var.
10976 { 10977 struct ast_variable *varlist; 10978 int i; 10979 10980 if (argc < 4) 10981 return RESULT_SHOWUSAGE; 10982 10983 if (!notify_types) { 10984 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 10985 return RESULT_FAILURE; 10986 } 10987 10988 varlist = ast_variable_browse(notify_types, argv[2]); 10989 10990 if (!varlist) { 10991 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 10992 return RESULT_FAILURE; 10993 } 10994 10995 for (i = 3; i < argc; i++) { 10996 struct sip_pvt *p; 10997 struct sip_request req; 10998 struct ast_variable *var; 10999 11000 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { 11001 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 11002 return RESULT_FAILURE; 11003 } 11004 11005 if (create_addr(p, argv[i])) { 11006 /* Maybe they're not registered, etc. */ 11007 sip_destroy(p); 11008 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 11009 continue; 11010 } 11011 11012 initreqprep(&req, p, SIP_NOTIFY); 11013 11014 for (var = varlist; var; var = var->next) 11015 add_header(&req, var->name, var->value); 11016 11017 /* Recalculate our side, and recalculate Call ID */ 11018 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 11019 p->ourip = __ourip; 11020 build_via(p); 11021 build_callid_pvt(p); 11022 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 11023 transmit_sip_request(p, &req); 11024 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11025 } 11026 11027 return RESULT_SUCCESS; 11028 }
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 12657 of file chan_sip.c.
References ast_channel::amaflags, ast_calloc, AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc(), ast_channel_lock, ast_channel_masquerade(), ast_channel_unlock, ast_do_masquerade(), ast_hangup(), ast_log(), ast_pthread_create_background, AST_STATE_DOWN, ast_channel::context, copy_request(), ast_channel::exten, free, ast_channel::hangupcause, LOG_DEBUG, LOG_WARNING, option_debug, ast_channel::priority, ast_channel::readformat, sip_park_thread(), and ast_channel::writeformat.
Referenced by handle_request_refer().
12658 { 12659 struct sip_dual *d; 12660 struct ast_channel *transferee, *transferer; 12661 /* Chan2m: The transferer, chan1m: The transferee */ 12662 pthread_t th; 12663 12664 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 12665 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); 12666 if ((!transferer) || (!transferee)) { 12667 if (transferee) { 12668 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 12669 ast_hangup(transferee); 12670 } 12671 if (transferer) { 12672 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 12673 ast_hangup(transferer); 12674 } 12675 return -1; 12676 } 12677 12678 /* Make formats okay */ 12679 transferee->readformat = chan1->readformat; 12680 transferee->writeformat = chan1->writeformat; 12681 12682 /* Prepare for taking over the channel */ 12683 ast_channel_masquerade(transferee, chan1); 12684 12685 /* Setup the extensions and such */ 12686 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 12687 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 12688 transferee->priority = chan1->priority; 12689 12690 /* We make a clone of the peer channel too, so we can play 12691 back the announcement */ 12692 12693 /* Make formats okay */ 12694 transferer->readformat = chan2->readformat; 12695 transferer->writeformat = chan2->writeformat; 12696 12697 /* Prepare for taking over the channel */ 12698 ast_channel_masquerade(transferer, chan2); 12699 12700 /* Setup the extensions and such */ 12701 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 12702 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 12703 transferer->priority = chan2->priority; 12704 12705 ast_channel_lock(transferer); 12706 if (ast_do_masquerade(transferer)) { 12707 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 12708 ast_channel_unlock(transferer); 12709 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 12710 ast_hangup(transferer); 12711 return -1; 12712 } 12713 ast_channel_unlock(transferer); 12714 if (!transferer || !transferee) { 12715 if (!transferer) { 12716 if (option_debug) 12717 ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n"); 12718 } 12719 if (!transferee) { 12720 if (option_debug) 12721 ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n"); 12722 } 12723 return -1; 12724 } 12725 if ((d = ast_calloc(1, sizeof(*d)))) { 12726 pthread_attr_t attr; 12727 12728 pthread_attr_init(&attr); 12729 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 12730 12731 /* Save original request for followup */ 12732 copy_request(&d->req, req); 12733 d->chan1 = transferee; /* Transferee */ 12734 d->chan2 = transferer; /* Transferer */ 12735 d->seqno = seqno; 12736 if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) { 12737 /* Could not start thread */ 12738 free(d); /* We don't need it anymore. If thread is created, d will be free'd 12739 by sip_park_thread() */ 12740 pthread_attr_destroy(&attr); 12741 return 0; 12742 } 12743 pthread_attr_destroy(&attr); 12744 } 12745 return -1; 12746 }
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 12590 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().
12591 { 12592 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 12593 struct sip_dual *d; 12594 struct sip_request req; 12595 int ext; 12596 int res; 12597 12598 d = stuff; 12599 transferee = d->chan1; 12600 transferer = d->chan2; 12601 copy_request(&req, &d->req); 12602 free(d); 12603 12604 if (!transferee || !transferer) { 12605 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 12606 return NULL; 12607 } 12608 if (option_debug > 3) 12609 ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 12610 12611 ast_channel_lock(transferee); 12612 if (ast_do_masquerade(transferee)) { 12613 ast_log(LOG_WARNING, "Masquerade failed.\n"); 12614 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 12615 ast_channel_unlock(transferee); 12616 return NULL; 12617 } 12618 ast_channel_unlock(transferee); 12619 12620 res = ast_park_call(transferee, transferer, 0, &ext); 12621 12622 12623 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 12624 if (!res) { 12625 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 12626 } else { 12627 /* Then tell the transferer what happened */ 12628 sprintf(buf, "Call parked on extension '%d'", ext); 12629 transmit_message_with_text(transferer->tech_pvt, buf); 12630 } 12631 #endif 12632 12633 /* Any way back to the current call??? */ 12634 /* Transmit response to the REFER request */ 12635 transmit_response(transferer->tech_pvt, "202 Accepted", &req); 12636 if (!res) { 12637 /* Transfer succeeded */ 12638 append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext); 12639 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 12640 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 12641 ast_hangup(transferer); /* This will cause a BYE */ 12642 if (option_debug) 12643 ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext); 12644 } else { 12645 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 12646 append_history(transferer->tech_pvt, "SIPpark","Parking failed\n"); 12647 if (option_debug) 12648 ast_log(LOG_DEBUG, "SIP Call parked failed \n"); 12649 /* Do not hangup call */ 12650 } 12651 return NULL; 12652 }
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 8208 of file chan_sip.c.
References ast_device_state_changed(), find_peer(), and sip_peer::onHold.
Referenced by process_sdp(), and update_call_counter().
08209 { 08210 struct sip_peer *peer = find_peer(p->peername, NULL, 1); 08211 08212 if (!peer) 08213 return; 08214 08215 /* If they put someone on hold, increment the value... otherwise decrement it */ 08216 if (hold) 08217 peer->onHold++; 08218 else 08219 peer->onHold--; 08220 08221 /* Request device state update */ 08222 ast_device_state_changed("SIP/%s", peer->name); 08223 08224 return; 08225 }
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 17184 of file chan_sip.c.
References ast_sched_add(), ast_sched_del(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, peerl, sched, and sip_poke_peer_s().
Referenced by load_module().
17185 { 17186 int ms = 0; 17187 17188 if (!speerobjs) /* No peers, just give up */ 17189 return; 17190 17191 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 17192 ASTOBJ_WRLOCK(iterator); 17193 if (iterator->pokeexpire > -1) 17194 ast_sched_del(sched, iterator->pokeexpire); 17195 ms += 100; 17196 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, iterator); 17197 ASTOBJ_UNLOCK(iterator); 17198 } while (0) 17199 ); 17200 }
static int sip_poke_noanswer | ( | void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 15214 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, sched, sip_destroy(), and sip_poke_peer_s().
Referenced by sip_poke_peer().
15215 { 15216 struct sip_peer *peer = data; 15217 15218 peer->pokeexpire = -1; 15219 if (peer->lastms > -1) { 15220 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 15221 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 15222 } 15223 if (peer->call) 15224 sip_destroy(peer->call); 15225 peer->call = NULL; 15226 peer->lastms = -1; 15227 ast_device_state_changed("SIP/%s", peer->name); 15228 /* Try again quickly */ 15229 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 15230 return 0; 15231 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 15236 of file chan_sip.c.
References __ourip, sip_peer::addr, ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_set, ast_strlen_zero(), build_callid_pvt(), build_via(), sip_peer::call, DEFAULT_MAXMS, sip_peer::flags, sip_pvt::flags, sip_peer::fullcontact, sip_peer::lastms, LOG_NOTICE, sip_peer::maxms, sip_pvt::ourip, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::recv, sip_pvt::relatedpeer, sip_pvt::sa, sched, sip_alloc(), sip_destroy(), SIP_FLAGS_TO_COPY, SIP_INVITE, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_FLAGS_TO_COPY, sip_poke_noanswer(), sipdebug, sip_peer::tohost, and transmit_invite().
Referenced by parse_register_contact(), reg_source_db(), and sip_poke_peer_s().
15237 { 15238 struct sip_pvt *p; 15239 15240 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 15241 /* IF we have no IP, or this isn't to be monitored, return 15242 imeediately after clearing things out */ 15243 if (peer->pokeexpire > -1) 15244 ast_sched_del(sched, peer->pokeexpire); 15245 peer->lastms = 0; 15246 peer->pokeexpire = -1; 15247 peer->call = NULL; 15248 return 0; 15249 } 15250 if (peer->call) { 15251 if (sipdebug) 15252 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 15253 sip_destroy(peer->call); 15254 } 15255 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS))) 15256 return -1; 15257 15258 p->sa = peer->addr; 15259 p->recv = peer->addr; 15260 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 15261 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 15262 15263 /* Send OPTIONs to peer's fullcontact */ 15264 if (!ast_strlen_zero(peer->fullcontact)) 15265 ast_string_field_set(p, fullcontact, peer->fullcontact); 15266 15267 if (!ast_strlen_zero(peer->tohost)) 15268 ast_string_field_set(p, tohost, peer->tohost); 15269 else 15270 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 15271 15272 /* Recalculate our side, and recalculate Call ID */ 15273 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15274 p->ourip = __ourip; 15275 build_via(p); 15276 build_callid_pvt(p); 15277 15278 if (peer->pokeexpire > -1) 15279 ast_sched_del(sched, peer->pokeexpire); 15280 p->relatedpeer = peer; 15281 ast_set_flag(&p->flags[0], SIP_OUTGOING); 15282 #ifdef VOCAL_DATA_HACK 15283 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 15284 transmit_invite(p, SIP_INVITE, 0, 2); 15285 #else 15286 transmit_invite(p, SIP_OPTIONS, 0, 2); 15287 #endif 15288 gettimeofday(&peer->ps, NULL); 15289 peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer); 15290 15291 return 0; 15292 }
static int sip_poke_peer_s | ( | void * | data | ) | [static] |
Poke peer (send qualify to check if peer is alive and well).
Definition at line 7611 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().
07612 { 07613 struct sip_peer *peer = data; 07614 07615 peer->pokeexpire = -1; 07616 sip_poke_peer(peer); 07617 return 0; 07618 }
static int sip_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 9768 of file chan_sip.c.
References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, name, peerl, RESULT_SHOWUSAGE, sip_destroy_peer(), SIP_PAGE2_RTCACHEFRIENDS, and TRUE.
09769 { 09770 struct sip_peer *peer; 09771 struct sip_user *user; 09772 int pruneuser = FALSE; 09773 int prunepeer = FALSE; 09774 int multi = FALSE; 09775 char *name = NULL; 09776 regex_t regexbuf; 09777 09778 switch (argc) { 09779 case 4: 09780 if (!strcasecmp(argv[3], "user")) 09781 return RESULT_SHOWUSAGE; 09782 if (!strcasecmp(argv[3], "peer")) 09783 return RESULT_SHOWUSAGE; 09784 if (!strcasecmp(argv[3], "like")) 09785 return RESULT_SHOWUSAGE; 09786 if (!strcasecmp(argv[3], "all")) { 09787 multi = TRUE; 09788 pruneuser = prunepeer = TRUE; 09789 } else { 09790 pruneuser = prunepeer = TRUE; 09791 name = argv[3]; 09792 } 09793 break; 09794 case 5: 09795 if (!strcasecmp(argv[4], "like")) 09796 return RESULT_SHOWUSAGE; 09797 if (!strcasecmp(argv[3], "all")) 09798 return RESULT_SHOWUSAGE; 09799 if (!strcasecmp(argv[3], "like")) { 09800 multi = TRUE; 09801 name = argv[4]; 09802 pruneuser = prunepeer = TRUE; 09803 } else if (!strcasecmp(argv[3], "user")) { 09804 pruneuser = TRUE; 09805 if (!strcasecmp(argv[4], "all")) 09806 multi = TRUE; 09807 else 09808 name = argv[4]; 09809 } else if (!strcasecmp(argv[3], "peer")) { 09810 prunepeer = TRUE; 09811 if (!strcasecmp(argv[4], "all")) 09812 multi = TRUE; 09813 else 09814 name = argv[4]; 09815 } else 09816 return RESULT_SHOWUSAGE; 09817 break; 09818 case 6: 09819 if (strcasecmp(argv[4], "like")) 09820 return RESULT_SHOWUSAGE; 09821 if (!strcasecmp(argv[3], "user")) { 09822 pruneuser = TRUE; 09823 name = argv[5]; 09824 } else if (!strcasecmp(argv[3], "peer")) { 09825 prunepeer = TRUE; 09826 name = argv[5]; 09827 } else 09828 return RESULT_SHOWUSAGE; 09829 break; 09830 default: 09831 return RESULT_SHOWUSAGE; 09832 } 09833 09834 if (multi && name) { 09835 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 09836 return RESULT_SHOWUSAGE; 09837 } 09838 09839 if (multi) { 09840 if (prunepeer) { 09841 int pruned = 0; 09842 09843 ASTOBJ_CONTAINER_WRLOCK(&peerl); 09844 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09845 ASTOBJ_RDLOCK(iterator); 09846 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09847 ASTOBJ_UNLOCK(iterator); 09848 continue; 09849 }; 09850 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 09851 ASTOBJ_MARK(iterator); 09852 pruned++; 09853 } 09854 ASTOBJ_UNLOCK(iterator); 09855 } while (0) ); 09856 if (pruned) { 09857 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 09858 ast_cli(fd, "%d peers pruned.\n", pruned); 09859 } else 09860 ast_cli(fd, "No peers found to prune.\n"); 09861 ASTOBJ_CONTAINER_UNLOCK(&peerl); 09862 } 09863 if (pruneuser) { 09864 int pruned = 0; 09865 09866 ASTOBJ_CONTAINER_WRLOCK(&userl); 09867 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09868 ASTOBJ_RDLOCK(iterator); 09869 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09870 ASTOBJ_UNLOCK(iterator); 09871 continue; 09872 }; 09873 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 09874 ASTOBJ_MARK(iterator); 09875 pruned++; 09876 } 09877 ASTOBJ_UNLOCK(iterator); 09878 } while (0) ); 09879 if (pruned) { 09880 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 09881 ast_cli(fd, "%d users pruned.\n", pruned); 09882 } else 09883 ast_cli(fd, "No users found to prune.\n"); 09884 ASTOBJ_CONTAINER_UNLOCK(&userl); 09885 } 09886 } else { 09887 if (prunepeer) { 09888 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 09889 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 09890 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 09891 ASTOBJ_CONTAINER_LINK(&peerl, peer); 09892 } else 09893 ast_cli(fd, "Peer '%s' pruned.\n", name); 09894 ASTOBJ_UNREF(peer, sip_destroy_peer); 09895 } else 09896 ast_cli(fd, "Peer '%s' not found.\n", name); 09897 } 09898 if (pruneuser) { 09899 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 09900 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 09901 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 09902 ASTOBJ_CONTAINER_LINK(&userl, user); 09903 } else 09904 ast_cli(fd, "User '%s' pruned.\n", name); 09905 ASTOBJ_UNREF(user, sip_destroy_user); 09906 } else 09907 ast_cli(fd, "User '%s' not found.\n", name); 09908 } 09909 } 09910 09911 return RESULT_SUCCESS; 09912 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static] |
Read SIP RTP from channel.
Definition at line 4120 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().
04121 { 04122 struct ast_frame *fr; 04123 struct sip_pvt *p; 04124 04125 if( ast == NULL ) 04126 return NULL; 04127 04128 p = ast->tech_pvt; 04129 int faxdetected = FALSE; 04130 04131 if( p == NULL ) 04132 return NULL; 04133 04134 ast_mutex_lock(&p->lock); 04135 fr = sip_rtp_read(ast, p, &faxdetected); 04136 p->lastrtprx = time(NULL); 04137 04138 /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */ 04139 /* 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 */ 04140 if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) { 04141 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 04142 if (!p->pendinginvite) { 04143 if (option_debug > 2) 04144 ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name); 04145 p->t38.state = T38_LOCAL_REINVITE; 04146 transmit_reinvite_with_t38_sdp(p); 04147 if (option_debug > 1) 04148 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name); 04149 } 04150 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04151 if (option_debug > 2) 04152 ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name); 04153 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04154 } 04155 } 04156 04157 ast_mutex_unlock(&p->lock); 04158 return fr; 04159 }
static struct sockaddr_in * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static] |
The real destination address for a write.
Definition at line 1728 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().
01729 { 01730 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa; 01731 }
static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 7422 of file chan_sip.c.
References ast_calloc, and sip_pvt::refer.
Referenced by handle_request_invite(), handle_request_refer(), and transmit_refer().
07423 { 07424 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 07425 return p->refer ? 1 : 0; 07426 }
static int sip_reg_timeout | ( | void * | data | ) | [static] |
Registration timeout, register again.
Definition at line 7179 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().
07180 { 07181 07182 /* if we are here, our registration timed out, so we'll just do it over */ 07183 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 07184 struct sip_pvt *p; 07185 int res; 07186 07187 /* if we couldn't get a reference to the registry object, punt */ 07188 if (!r) 07189 return 0; 07190 07191 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 07192 if (r->call) { 07193 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 07194 in the single SIP manager thread. */ 07195 p = r->call; 07196 if (p->registry) 07197 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 07198 r->call = NULL; 07199 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 07200 /* Pretend to ACK anything just in case */ 07201 __sip_pretend_ack(p); /* XXX we need p locked, not sure we have */ 07202 } 07203 /* If we have a limit, stop registration and give up */ 07204 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 07205 /* Ok, enough is enough. Don't try any more */ 07206 /* We could add an external notification here... 07207 steal it from app_voicemail :-) */ 07208 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 07209 r->regstate = REG_STATE_FAILED; 07210 } else { 07211 r->regstate = REG_STATE_UNREGISTERED; 07212 r->timeout = -1; 07213 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 07214 } 07215 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)); 07216 ASTOBJ_UNREF(r, sip_registry_destroy); 07217 return 0; 07218 }
static int sip_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 4447 of file chan_sip.c.
References ast_calloc, ast_log(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, FALSE, free, hostname, INITIAL_CSEQ, LOG_ERROR, LOG_WARNING, regl, secret, sip_registry_destroy(), and username.
04448 { 04449 struct sip_registry *reg; 04450 int portnum = 0; 04451 char username[256] = ""; 04452 char *hostname=NULL, *secret=NULL, *authuser=NULL; 04453 char *porta=NULL; 04454 char *contact=NULL; 04455 04456 if (!value) 04457 return -1; 04458 ast_copy_string(username, value, sizeof(username)); 04459 /* First split around the last '@' then parse the two components. */ 04460 hostname = strrchr(username, '@'); /* allow @ in the first part */ 04461 if (hostname) 04462 *hostname++ = '\0'; 04463 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 04464 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 04465 return -1; 04466 } 04467 /* split user[:secret[:authuser]] */ 04468 secret = strchr(username, ':'); 04469 if (secret) { 04470 *secret++ = '\0'; 04471 authuser = strchr(secret, ':'); 04472 if (authuser) 04473 *authuser++ = '\0'; 04474 } 04475 /* split host[:port][/contact] */ 04476 contact = strchr(hostname, '/'); 04477 if (contact) 04478 *contact++ = '\0'; 04479 if (ast_strlen_zero(contact)) 04480 contact = "s"; 04481 porta = strchr(hostname, ':'); 04482 if (porta) { 04483 *porta++ = '\0'; 04484 portnum = atoi(porta); 04485 if (portnum == 0) { 04486 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 04487 return -1; 04488 } 04489 } 04490 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 04491 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 04492 return -1; 04493 } 04494 04495 if (ast_string_field_init(reg, 256)) { 04496 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 04497 free(reg); 04498 return -1; 04499 } 04500 04501 regobjs++; 04502 ASTOBJ_INIT(reg); 04503 ast_string_field_set(reg, contact, contact); 04504 if (username) 04505 ast_string_field_set(reg, username, username); 04506 if (hostname) 04507 ast_string_field_set(reg, hostname, hostname); 04508 if (authuser) 04509 ast_string_field_set(reg, authuser, authuser); 04510 if (secret) 04511 ast_string_field_set(reg, secret, secret); 04512 reg->expire = -1; 04513 reg->timeout = -1; 04514 reg->refresh = default_expiry; 04515 reg->portno = portnum; 04516 reg->callid_valid = FALSE; 04517 reg->ocseq = INITIAL_CSEQ; 04518 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 04519 ASTOBJ_UNREF(reg,sip_registry_destroy); 04520 return 0; 04521 }
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 2860 of file chan_sip.c.
References ast_log(), ast_sched_del(), ast_string_field_free_pools, sip_registry::call, sip_registry::expire, free, LOG_DEBUG, option_debug, sip_pvt::registry, sched, sip_destroy(), and sip_registry::timeout.
Referenced by __sip_destroy(), handle_response_register(), sip_reg_timeout(), sip_register(), sip_reregister(), and unload_module().
02861 { 02862 /* Really delete */ 02863 if (option_debug > 2) 02864 ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 02865 02866 if (reg->call) { 02867 /* Clear registry before destroying to ensure 02868 we don't get reentered trying to grab the registry lock */ 02869 reg->call->registry = NULL; 02870 if (option_debug > 2) 02871 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 02872 sip_destroy(reg->call); 02873 } 02874 if (reg->expire > -1) 02875 ast_sched_del(sched, reg->expire); 02876 if (reg->timeout > -1) 02877 ast_sched_del(sched, reg->timeout); 02878 ast_string_field_free_pools(reg); 02879 regobjs--; 02880 free(reg); 02881 02882 }
static int sip_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Force reload of module from cli.
Definition at line 17276 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().
17277 { 17278 ast_mutex_lock(&sip_reload_lock); 17279 if (sip_reloading) 17280 ast_verbose("Previous SIP reload not yet done\n"); 17281 else { 17282 sip_reloading = TRUE; 17283 if (fd) 17284 sip_reloadreason = CHANNEL_CLI_RELOAD; 17285 else 17286 sip_reloadreason = CHANNEL_MODULE_RELOAD; 17287 } 17288 ast_mutex_unlock(&sip_reload_lock); 17289 restart_monitor(); 17290 17291 return 0; 17292 }
static struct ast_channel * sip_request_call | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.
Definition at line 15394 of file chan_sip.c.
References __ourip, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, AST_FORMAT_MAX_AUDIO, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), build_callid_pvt(), build_via(), create_addr(), ext, sip_pvt::flags, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, option_debug, sip_pvt::options, restart_monitor(), sip_alloc(), sip_destroy(), SIP_INVITE, sip_new(), SIP_PAGE2_OUTGOING_CALL, and username.
15395 { 15396 int oldformat; 15397 struct sip_pvt *p; 15398 struct ast_channel *tmpc = NULL; 15399 char *ext, *host; 15400 char tmp[256]; 15401 char *dest = data; 15402 15403 oldformat = format; 15404 if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { 15405 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)); 15406 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 15407 return NULL; 15408 } 15409 if (option_debug) 15410 ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 15411 15412 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { 15413 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data); 15414 *cause = AST_CAUSE_SWITCH_CONGESTION; 15415 return NULL; 15416 } 15417 15418 ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL); 15419 15420 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 15421 sip_destroy(p); 15422 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 15423 *cause = AST_CAUSE_SWITCH_CONGESTION; 15424 return NULL; 15425 } 15426 15427 ast_copy_string(tmp, dest, sizeof(tmp)); 15428 host = strchr(tmp, '@'); 15429 if (host) { 15430 *host++ = '\0'; 15431 ext = tmp; 15432 } else { 15433 ext = strchr(tmp, '/'); 15434 if (ext) 15435 *ext++ = '\0'; 15436 host = tmp; 15437 } 15438 15439 if (create_addr(p, host)) { 15440 *cause = AST_CAUSE_UNREGISTERED; 15441 if (option_debug > 2) 15442 ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n"); 15443 sip_destroy(p); 15444 return NULL; 15445 } 15446 if (ast_strlen_zero(p->peername) && ext) 15447 ast_string_field_set(p, peername, ext); 15448 /* Recalculate our side, and recalculate Call ID */ 15449 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15450 p->ourip = __ourip; 15451 build_via(p); 15452 build_callid_pvt(p); 15453 15454 /* We have an extension to call, don't use the full contact here */ 15455 /* This to enable dialing registered peers with extension dialling, 15456 like SIP/peername/extension 15457 SIP/peername will still use the full contact */ 15458 if (ext) { 15459 ast_string_field_set(p, username, ext); 15460 ast_string_field_free(p, fullcontact); 15461 } 15462 #if 0 15463 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 15464 #endif 15465 p->prefcodec = oldformat; /* Format for this call */ 15466 ast_mutex_lock(&p->lock); 15467 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 15468 ast_mutex_unlock(&p->lock); 15469 if (!tmpc) 15470 sip_destroy(p); 15471 ast_update_use_count(); 15472 restart_monitor(); 15473 return tmpc; 15474 }
static int sip_reregister | ( | void * | data | ) | [static] |
Update registration with SIP Proxy.
Definition at line 7147 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().
07148 { 07149 /* if we are here, we know that we need to reregister. */ 07150 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 07151 07152 /* if we couldn't get a reference to the registry object, punt */ 07153 if (!r) 07154 return 0; 07155 07156 if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 07157 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 07158 /* Since registry's are only added/removed by the the monitor thread, this 07159 may be overkill to reference/dereference at all here */ 07160 if (sipdebug) 07161 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 07162 07163 r->expire = -1; 07164 __sip_do_register(r); 07165 ASTOBJ_UNREF(r, sip_registry_destroy); 07166 return 0; 07167 }
static struct ast_frame * sip_rtp_read | ( | struct ast_channel * | ast, | |
struct sip_pvt * | p, | |||
int * | faxdetect | |||
) | [static] |
Read RTP from network.
Definition at line 4050 of file chan_sip.c.
References ast_dsp_process(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_null_frame, ast_rtcp_read(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_udptl_read(), f, ast_channel::fdno, sip_pvt::flags, sip_pvt::jointcapability, LOG_DEBUG, ast_channel::nativeformats, option_debug, sip_pvt::owner, ast_channel::readformat, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_PAGE2_T38SUPPORT_UDPTL, sip_pvt::t38, t38properties::t38support, sip_pvt::udptl, sip_pvt::vad, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by sip_read().
04051 { 04052 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 04053 struct ast_frame *f; 04054 04055 if (!p->rtp) { 04056 /* We have no RTP allocated for this channel */ 04057 return &ast_null_frame; 04058 } 04059 04060 switch(ast->fdno) { 04061 case 0: 04062 f = ast_rtp_read(p->rtp); /* RTP Audio */ 04063 break; 04064 case 1: 04065 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 04066 break; 04067 case 2: 04068 f = ast_rtp_read(p->vrtp); /* RTP Video */ 04069 break; 04070 case 3: 04071 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 04072 break; 04073 case 5: 04074 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 04075 break; 04076 default: 04077 f = &ast_null_frame; 04078 } 04079 /* Don't forward RFC2833 if we're not supposed to */ 04080 if (f && (f->frametype == AST_FRAME_DTMF) && 04081 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) 04082 return &ast_null_frame; 04083 04084 /* We already hold the channel lock */ 04085 if (!p->owner || f->frametype != AST_FRAME_VOICE) 04086 return f; 04087 04088 if (f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 04089 if (!(f->subclass & p->jointcapability)) { 04090 if (option_debug) { 04091 ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n", 04092 ast_getformatname(f->subclass), p->owner->name); 04093 } 04094 return &ast_null_frame; 04095 } 04096 if (option_debug) 04097 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 04098 p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; 04099 ast_set_read_format(p->owner, p->owner->readformat); 04100 ast_set_write_format(p->owner, p->owner->writeformat); 04101 } 04102 04103 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 04104 f = ast_dsp_process(p->owner, p->vad, f); 04105 if (f && f->frametype == AST_FRAME_DTMF) { 04106 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') { 04107 if (option_debug) 04108 ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name); 04109 *faxdetect = 1; 04110 } else if (option_debug) { 04111 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 04112 } 04113 } 04114 } 04115 04116 return f; 04117 }
static void sip_scheddestroy | ( | struct sip_pvt * | p, | |
int | ms | |||
) | [static] |
Schedule destruction of SIP dialog.
Definition at line 2028 of file chan_sip.c.
References __sip_autodestruct(), append_history, ast_sched_add(), ast_sched_del(), ast_test_flag, ast_verbose(), sip_pvt::flags, sip_pvt::method, sched, sip_debug_test_pvt(), sip_methods, SIP_NO_HISTORY, cfsip_methods::text, and sip_pvt::timer_t1.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), and sip_sipredirect().
02029 { 02030 if (ms < 0) { 02031 if (p->timer_t1 == 0) 02032 p->timer_t1 = 500; /* Set timer T1 if not set (RFC 3261) */ 02033 ms = p->timer_t1 * 64; 02034 } 02035 if (sip_debug_test_pvt(p)) 02036 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 02037 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 02038 append_history(p, "SchedDestroy", "%d ms", ms); 02039 02040 if (p->autokillid > -1) 02041 ast_sched_del(sched, p->autokillid); 02042 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 02043 }
static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 17203 of file chan_sip.c.
References ast_sched_add(), ast_sched_del(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, regl, sched, and sip_reregister().
Referenced by load_module().
17204 { 17205 int ms; 17206 int regspacing; 17207 if (!regobjs) 17208 return; 17209 regspacing = default_expiry * 1000/regobjs; 17210 if (regspacing > 100) 17211 regspacing = 100; 17212 ms = regspacing; 17213 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17214 ASTOBJ_WRLOCK(iterator); 17215 if (iterator->expire > -1) 17216 ast_sched_del(sched, iterator->expire); 17217 ms += regspacing; 17218 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 17219 ASTOBJ_UNLOCK(iterator); 17220 } while (0) 17221 ); 17222 }
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 14960 of file chan_sip.c.
References __ourip, sip_peer::addr, ast_app_inboxcount(), ast_set_flag, ast_sip_ouraddrfor(), build_callid_pvt(), build_via(), create_addr_from_peer(), sip_peer::defaddr, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, sip_peer::lastmsgcheck, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::mwipvt, sip_pvt::ourip, sip_pvt::sa, sip_alloc(), sip_destroy(), SIP_NOTIFY, SIP_OUTGOING, sip_scheddestroy(), transmit_notify_with_mwi(), and sip_peer::vmexten.
Referenced by handle_request_subscribe().
14961 { 14962 /* Called with peerl lock, but releases it */ 14963 struct sip_pvt *p; 14964 int newmsgs, oldmsgs; 14965 14966 /* Do we have an IP address? If not, skip this peer */ 14967 if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 14968 return 0; 14969 14970 /* Check for messages */ 14971 ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs); 14972 14973 peer->lastmsgcheck = time(NULL); 14974 14975 /* Return now if it's the same thing we told them last time */ 14976 if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) { 14977 return 0; 14978 } 14979 14980 14981 peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)); 14982 14983 if (peer->mwipvt) { 14984 /* Base message on subscription */ 14985 p = peer->mwipvt; 14986 } else { 14987 /* Build temporary dialog for this message */ 14988 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 14989 return -1; 14990 if (create_addr_from_peer(p, peer)) { 14991 /* Maybe they're not registered, etc. */ 14992 sip_destroy(p); 14993 return 0; 14994 } 14995 /* Recalculate our side, and recalculate Call ID */ 14996 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 14997 p->ourip = __ourip; 14998 build_via(p); 14999 build_callid_pvt(p); 15000 /* Destroy this session after 32 secs */ 15001 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15002 } 15003 /* Send MWI */ 15004 ast_set_flag(&p->flags[0], SIP_OUTGOING); 15005 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 15006 return 0; 15007 }
static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 3598 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.
03599 { 03600 struct sip_pvt *p = ast->tech_pvt; 03601 int res = 0; 03602 03603 ast_mutex_lock(&p->lock); 03604 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03605 case SIP_DTMF_INBAND: 03606 res = -1; /* Tell Asterisk to generate inband indications */ 03607 break; 03608 case SIP_DTMF_RFC2833: 03609 if (p->rtp) 03610 ast_rtp_senddigit_begin(p->rtp, digit); 03611 break; 03612 default: 03613 break; 03614 } 03615 ast_mutex_unlock(&p->lock); 03616 03617 return res; 03618 }
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 3622 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit_end(), ast_test_flag, sip_pvt::flags, sip_pvt::lock, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, ast_channel::tech_pvt, and transmit_info_with_digit().
03623 { 03624 struct sip_pvt *p = ast->tech_pvt; 03625 int res = 0; 03626 03627 ast_mutex_lock(&p->lock); 03628 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03629 case SIP_DTMF_INFO: 03630 transmit_info_with_digit(p, digit, duration); 03631 break; 03632 case SIP_DTMF_RFC2833: 03633 if (p->rtp) 03634 ast_rtp_senddigit_end(p->rtp, digit); 03635 break; 03636 case SIP_DTMF_INBAND: 03637 res = -1; /* Tell Asterisk to stop inband indications */ 03638 break; 03639 } 03640 ast_mutex_unlock(&p->lock); 03641 03642 return res; 03643 }
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 2271 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().
02272 { 02273 struct sip_pvt *p = ast->tech_pvt; 02274 int debug = sip_debug_test_pvt(p); 02275 02276 if (debug) 02277 ast_verbose("Sending text %s on %s\n", text, ast->name); 02278 if (!p) 02279 return -1; 02280 if (ast_strlen_zero(text)) 02281 return 0; 02282 if (debug) 02283 ast_verbose("Really sending text %s on %s\n", text, ast->name); 02284 transmit_message_with_text(p, text); 02285 return 0; 02286 }
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 16942 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::flags, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, SIP_ALREADYGONE, SIP_CAN_REINVITE_NAT, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), sip_pvt::vredirip, and sip_pvt::vrtp.
16943 { 16944 struct sip_pvt *p; 16945 int changed = 0; 16946 16947 p = chan->tech_pvt; 16948 if (!p) 16949 return -1; 16950 16951 /* Disable early RTP bridge */ 16952 if (chan->_state != AST_STATE_UP && !global_directrtpsetup) /* We are in early state */ 16953 return 0; 16954 16955 ast_mutex_lock(&p->lock); 16956 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 16957 /* If we're destroyed, don't bother */ 16958 ast_mutex_unlock(&p->lock); 16959 return 0; 16960 } 16961 16962 /* if this peer cannot handle reinvites of the media stream to devices 16963 that are known to be behind a NAT, then stop the process now 16964 */ 16965 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 16966 ast_mutex_unlock(&p->lock); 16967 return 0; 16968 } 16969 16970 if (rtp) { 16971 changed |= ast_rtp_get_peer(rtp, &p->redirip); 16972 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 16973 memset(&p->redirip, 0, sizeof(p->redirip)); 16974 changed = 1; 16975 } 16976 if (vrtp) { 16977 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 16978 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 16979 memset(&p->vredirip, 0, sizeof(p->vredirip)); 16980 changed = 1; 16981 } 16982 if (codecs && (p->redircodecs != codecs)) { 16983 p->redircodecs = codecs; 16984 changed = 1; 16985 } 16986 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 16987 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 16988 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 16989 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 16990 if (option_debug) 16991 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)); 16992 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 16993 if (option_debug > 2) { 16994 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)); 16995 } 16996 transmit_reinvite_with_sdp(p); 16997 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 16998 if (option_debug > 2) { 16999 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)); 17000 } 17001 /* We have a pending Invite. Send re-invite when we're done with the invite */ 17002 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 17003 } 17004 } 17005 /* Reset lastrtprx timer */ 17006 p->lastrtprx = p->lastrtptx = time(NULL); 17007 ast_mutex_unlock(&p->lock); 17008 return 0; 17009 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 16769 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_udptl_get_peer(), sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, sip_pvt::ourip, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), sip_pvt::udptl, and sip_pvt::udptlredirip.
16770 { 16771 struct sip_pvt *p; 16772 16773 p = chan->tech_pvt; 16774 if (!p) 16775 return -1; 16776 ast_mutex_lock(&p->lock); 16777 if (udptl) 16778 ast_udptl_get_peer(udptl, &p->udptlredirip); 16779 else 16780 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 16781 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 16782 if (!p->pendinginvite) { 16783 if (option_debug > 2) { 16784 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); 16785 } 16786 transmit_reinvite_with_t38_sdp(p); 16787 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 16788 if (option_debug > 2) { 16789 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); 16790 } 16791 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 16792 } 16793 } 16794 /* Reset lastrtprx timer */ 16795 p->lastrtprx = p->lastrtptx = time(NULL); 16796 ast_mutex_unlock(&p->lock); 16797 return 0; 16798 }
static int sip_show_channel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show details of one active dialog.
Definition at line 10642 of file chan_sip.c.
References sip_pvt::allowtransfer, ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_strlen_zero(), ast_test_flag, sip_pvt::capability, dtmfmode2str(), sip_pvt::flags, sip_route::hop, iflist, sip_pvt::jointcapability, sip_pvt::lastmsg, len, sip_pvt::maxcallbitrate, nat2str(), ast_channel::nativeformats, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::recv, sip_pvt::redirip, RESULT_SHOWUSAGE, sip_pvt::route, sip_pvt::sa, SIP_DTMF, SIP_NAT, SIP_NEEDDESTROY, sip_options, SIP_OUTGOING, SIP_PROMISCREDIR, sip_pvt::sipoptions, sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, text, and transfermode2str().
10643 { 10644 struct sip_pvt *cur; 10645 size_t len; 10646 int found = 0; 10647 10648 if (argc != 4) 10649 return RESULT_SHOWUSAGE; 10650 len = strlen(argv[3]); 10651 ast_mutex_lock(&iflock); 10652 for (cur = iflist; cur; cur = cur->next) { 10653 if (!strncasecmp(cur->callid, argv[3], len)) { 10654 char formatbuf[BUFSIZ/2]; 10655 ast_cli(fd,"\n"); 10656 if (cur->subscribed != NONE) 10657 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 10658 else 10659 ast_cli(fd, " * SIP Call\n"); 10660 ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 10661 ast_cli(fd, " Call-ID: %s\n", cur->callid); 10662 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 10663 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 10664 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 10665 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 10666 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 10667 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 10668 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 10669 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 10670 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 10671 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 10672 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 10673 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)" ); 10674 ast_cli(fd, " Our Tag: %s\n", cur->tag); 10675 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 10676 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 10677 if (!ast_strlen_zero(cur->username)) 10678 ast_cli(fd, " Username: %s\n", cur->username); 10679 if (!ast_strlen_zero(cur->peername)) 10680 ast_cli(fd, " Peername: %s\n", cur->peername); 10681 if (!ast_strlen_zero(cur->uri)) 10682 ast_cli(fd, " Original uri: %s\n", cur->uri); 10683 if (!ast_strlen_zero(cur->cid_num)) 10684 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 10685 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 10686 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 10687 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 10688 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 10689 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 10690 ast_cli(fd, " SIP Options: "); 10691 if (cur->sipoptions) { 10692 int x; 10693 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10694 if (cur->sipoptions & sip_options[x].id) 10695 ast_cli(fd, "%s ", sip_options[x].text); 10696 } 10697 } else 10698 ast_cli(fd, "(none)\n"); 10699 ast_cli(fd, "\n\n"); 10700 found++; 10701 } 10702 } 10703 ast_mutex_unlock(&iflock); 10704 if (!found) 10705 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 10706 return RESULT_SUCCESS; 10707 }
static int sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP channels.
Definition at line 10440 of file chan_sip.c.
References __sip_show_channels().
10441 { 10442 return __sip_show_channels(fd, argc, argv, 0); 10443 }
static int sip_show_domains | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list local domains.
Definition at line 9946 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.
09947 { 09948 struct domain *d; 09949 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 09950 09951 if (AST_LIST_EMPTY(&domain_list)) { 09952 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 09953 return RESULT_SUCCESS; 09954 } else { 09955 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 09956 AST_LIST_LOCK(&domain_list); 09957 AST_LIST_TRAVERSE(&domain_list, d, list) 09958 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 09959 domain_mode_to_text(d->mode)); 09960 AST_LIST_UNLOCK(&domain_list); 09961 ast_cli(fd, "\n"); 09962 return RESULT_SUCCESS; 09963 } 09964 }
static int sip_show_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show history details of one dialog.
Definition at line 10710 of file chan_sip.c.
References ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock(), sip_pvt::history, iflist, len, sip_pvt::next, NONE, RESULT_SHOWUSAGE, and sip_pvt::subscribed.
10711 { 10712 struct sip_pvt *cur; 10713 size_t len; 10714 int found = 0; 10715 10716 if (argc != 4) 10717 return RESULT_SHOWUSAGE; 10718 if (!recordhistory) 10719 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 10720 len = strlen(argv[3]); 10721 ast_mutex_lock(&iflock); 10722 for (cur = iflist; cur; cur = cur->next) { 10723 if (!strncasecmp(cur->callid, argv[3], len)) { 10724 struct sip_history *hist; 10725 int x = 0; 10726 10727 ast_cli(fd,"\n"); 10728 if (cur->subscribed != NONE) 10729 ast_cli(fd, " * Subscription\n"); 10730 else 10731 ast_cli(fd, " * SIP Call\n"); 10732 if (cur->history) 10733 AST_LIST_TRAVERSE(cur->history, hist, list) 10734 ast_cli(fd, "%d. %s\n", ++x, hist->event); 10735 if (x == 0) 10736 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 10737 found++; 10738 } 10739 } 10740 ast_mutex_unlock(&iflock); 10741 if (!found) 10742 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 10743 return RESULT_SUCCESS; 10744 }
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 9371 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.
09372 { 09373 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 09374 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 09375 char ilimits[40]; 09376 char iused[40]; 09377 int showall = FALSE; 09378 09379 if (argc < 3) 09380 return RESULT_SHOWUSAGE; 09381 09382 if (argc == 4 && !strcmp(argv[3],"all")) 09383 showall = TRUE; 09384 09385 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 09386 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09387 ASTOBJ_RDLOCK(iterator); 09388 if (iterator->call_limit) 09389 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09390 else 09391 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09392 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 09393 if (showall || iterator->call_limit) 09394 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09395 ASTOBJ_UNLOCK(iterator); 09396 } while (0) ); 09397 09398 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 09399 09400 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09401 ASTOBJ_RDLOCK(iterator); 09402 if (iterator->call_limit) 09403 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09404 else 09405 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09406 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 09407 if (showall || iterator->call_limit) 09408 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09409 ASTOBJ_UNLOCK(iterator); 09410 } while (0) ); 09411 09412 return RESULT_SUCCESS; 09413 #undef FORMAT 09414 #undef FORMAT2 09415 }
static int sip_show_objects | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 9692 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
09693 { 09694 char tmp[256]; 09695 if (argc != 3) 09696 return RESULT_SHOWUSAGE; 09697 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 09698 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 09699 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 09700 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 09701 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 09702 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 09703 return RESULT_SUCCESS; 09704 }
static int sip_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 9998 of file chan_sip.c.
References _sip_show_peer().
09999 { 10000 return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); 10001 }
static int sip_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Show Peers command.
Definition at line 9548 of file chan_sip.c.
References _sip_show_peers().
09549 { 09550 return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); 09551 }
static int sip_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 10271 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.
10272 { 10273 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 10274 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 10275 char host[80]; 10276 char tmpdat[256]; 10277 struct tm tm; 10278 10279 10280 if (argc != 3) 10281 return RESULT_SHOWUSAGE; 10282 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 10283 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 10284 ASTOBJ_RDLOCK(iterator); 10285 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 10286 if (iterator->regtime) { 10287 ast_localtime(&iterator->regtime, &tm, NULL); 10288 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 10289 } else { 10290 tmpdat[0] = 0; 10291 } 10292 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 10293 ASTOBJ_UNLOCK(iterator); 10294 } while(0)); 10295 return RESULT_SUCCESS; 10296 #undef FORMAT 10297 #undef FORMAT2 10298 }
static int sip_show_settings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List global settings for the SIP channel.
Definition at line 10301 of file chan_sip.c.
References ast_check_realtime(), ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), AST_JB_ENABLED, AST_JB_FORCED, AST_JB_LOG, AST_LIST_EMPTY, ast_test_flag, ast_tos2str(), authl, bindaddr, default_prefs, dtmfmode2str(), global_flags, global_jbconf, ast_jb_conf::impl, ast_jb_conf::max_size, nat2str(), print_codec_to_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_jb_conf::resync_threshold, S_OR, SIP_DTMF, SIP_NAT, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTSAVE_SYSNAME, SIP_PAGE2_RTUPDATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, SIP_USECLIENTCODE, SIP_USEREQPHONE, and transfermode2str().
10302 { 10303 int realtimepeers; 10304 int realtimeusers; 10305 char codec_buf[BUFSIZ]; 10306 10307 realtimepeers = ast_check_realtime("sippeers"); 10308 realtimeusers = ast_check_realtime("sipusers"); 10309 10310 if (argc != 3) 10311 return RESULT_SHOWUSAGE; 10312 ast_cli(fd, "\n\nGlobal Settings:\n"); 10313 ast_cli(fd, "----------------\n"); 10314 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 10315 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 10316 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 10317 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 10318 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 10319 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10320 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10321 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 10322 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 10323 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 10324 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 10325 ast_cli(fd, " Our auth realm %s\n", global_realm); 10326 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 10327 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 10328 ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No"); 10329 ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No"); 10330 ast_cli(fd, " User Agent: %s\n", global_useragent); 10331 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 10332 ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 10333 ast_cli(fd, " Caller ID: %s\n", default_callerid); 10334 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 10335 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 10336 ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 10337 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 10338 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 10339 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 10340 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 10341 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10342 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 10343 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 10344 #endif 10345 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 10346 ast_cli(fd, " Jitterbuffer enabled: %s\n", ast_test_flag(&global_jbconf, AST_JB_ENABLED) ? "Yes" : "No"); 10347 ast_cli(fd, " Jitterbuffer forced: %s\n", ast_test_flag(&global_jbconf, AST_JB_FORCED) ? "Yes" : "No"); 10348 ast_cli(fd, " Jitterbuffer max size: %ld\n", global_jbconf.max_size); 10349 ast_cli(fd, " Jitterbuffer resync: %ld\n", global_jbconf.resync_threshold); 10350 ast_cli(fd, " Jitterbuffer impl: %s\n", global_jbconf.impl); 10351 ast_cli(fd, " Jitterbuffer log: %s\n", ast_test_flag(&global_jbconf, AST_JB_LOG) ? "Yes" : "No"); 10352 if (!realtimepeers && !realtimeusers) 10353 ast_cli(fd, " SIP realtime: Disabled\n" ); 10354 else 10355 ast_cli(fd, " SIP realtime: Enabled\n" ); 10356 10357 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 10358 ast_cli(fd, "---------------------------\n"); 10359 ast_cli(fd, " Codecs: "); 10360 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 10361 ast_cli(fd, "%s\n", codec_buf); 10362 ast_cli(fd, " Codec Order: "); 10363 print_codec_to_cli(fd, &default_prefs); 10364 ast_cli(fd, "\n"); 10365 ast_cli(fd, " T1 minimum: %d\n", global_t1min); 10366 ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No"); 10367 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 10368 ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 10369 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 10370 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 10371 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 10372 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 10373 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 10374 ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); 10375 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 10376 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 10377 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 10378 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 10379 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 10380 ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No"); 10381 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 10382 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate); 10383 ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No"); 10384 ast_cli(fd, "\nDefault Settings:\n"); 10385 ast_cli(fd, "-----------------\n"); 10386 ast_cli(fd, " Context: %s\n", default_context); 10387 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 10388 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 10389 ast_cli(fd, " Qualify: %d\n", default_qualify); 10390 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 10391 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" ); 10392 ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)")); 10393 ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); 10394 ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); 10395 ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); 10396 10397 10398 if (realtimepeers || realtimeusers) { 10399 ast_cli(fd, "\nRealtime SIP Settings:\n"); 10400 ast_cli(fd, "----------------------\n"); 10401 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 10402 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 10403 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 10404 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 10405 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 10406 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 10407 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 10408 } 10409 ast_cli(fd, "\n----\n"); 10410 return RESULT_SUCCESS; 10411 }
static int sip_show_subscriptions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP subscriptions.
Definition at line 10446 of file chan_sip.c.
References __sip_show_channels().
10447 { 10448 return __sip_show_channels(fd, argc, argv, 1); 10449 }
static int sip_show_user | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one user in detail.
Definition at line 10216 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.
10217 { 10218 char cbuf[256]; 10219 struct sip_user *user; 10220 struct ast_variable *v; 10221 int load_realtime; 10222 10223 if (argc < 4) 10224 return RESULT_SHOWUSAGE; 10225 10226 /* Load from realtime storage? */ 10227 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10228 10229 user = find_user(argv[3], load_realtime); 10230 if (user) { 10231 ast_cli(fd,"\n\n"); 10232 ast_cli(fd, " * Name : %s\n", user->name); 10233 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 10234 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 10235 ast_cli(fd, " Context : %s\n", user->context); 10236 ast_cli(fd, " Language : %s\n", user->language); 10237 if (!ast_strlen_zero(user->accountcode)) 10238 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 10239 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 10240 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 10241 ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 10242 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 10243 ast_cli(fd, " Call limit : %d\n", user->call_limit); 10244 ast_cli(fd, " Callgroup : "); 10245 print_group(fd, user->callgroup, 0); 10246 ast_cli(fd, " Pickupgroup : "); 10247 print_group(fd, user->pickupgroup, 0); 10248 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 10249 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 10250 ast_cli(fd, " Codec Order : ("); 10251 print_codec_to_cli(fd, &user->prefs); 10252 ast_cli(fd, ")\n"); 10253 10254 ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No"); 10255 if (user->chanvars) { 10256 ast_cli(fd, " Variables :\n"); 10257 for (v = user->chanvars ; v ; v = v->next) 10258 ast_cli(fd, " %s = %s\n", v->name, v->value); 10259 } 10260 ast_cli(fd,"\n"); 10261 ASTOBJ_UNREF(user,sip_destroy_user); 10262 } else { 10263 ast_cli(fd,"User %s not found.\n", argv[3]); 10264 ast_cli(fd,"\n"); 10265 } 10266 10267 return RESULT_SUCCESS; 10268 }
static int sip_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 9471 of file chan_sip.c.
References ast_cli(), ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, nat2str(), RESULT_SHOWUSAGE, SIP_NAT, TRUE, and userl.
09472 { 09473 regex_t regexbuf; 09474 int havepattern = FALSE; 09475 09476 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 09477 09478 switch (argc) { 09479 case 5: 09480 if (!strcasecmp(argv[3], "like")) { 09481 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 09482 return RESULT_SHOWUSAGE; 09483 havepattern = TRUE; 09484 } else 09485 return RESULT_SHOWUSAGE; 09486 case 3: 09487 break; 09488 default: 09489 return RESULT_SHOWUSAGE; 09490 } 09491 09492 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 09493 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09494 ASTOBJ_RDLOCK(iterator); 09495 09496 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09497 ASTOBJ_UNLOCK(iterator); 09498 continue; 09499 } 09500 09501 ast_cli(fd, FORMAT, iterator->name, 09502 iterator->secret, 09503 iterator->accountcode, 09504 iterator->context, 09505 iterator->ha ? "Yes" : "No", 09506 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 09507 ASTOBJ_UNLOCK(iterator); 09508 } while (0) 09509 ); 09510 09511 if (havepattern) 09512 regfree(®exbuf); 09513 09514 return RESULT_SUCCESS; 09515 #undef FORMAT 09516 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 17122 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(), strsep(), and transmit_response_reliable().
Referenced by sip_transfer().
17123 { 17124 char *cdest; 17125 char *extension, *host, *port; 17126 char tmp[80]; 17127 17128 cdest = ast_strdupa(dest); 17129 17130 extension = strsep(&cdest, "@"); 17131 host = strsep(&cdest, ":"); 17132 port = strsep(&cdest, ":"); 17133 if (ast_strlen_zero(extension)) { 17134 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 17135 return 0; 17136 } 17137 17138 /* we'll issue the redirect message here */ 17139 if (!host) { 17140 char *localtmp; 17141 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 17142 if (ast_strlen_zero(tmp)) { 17143 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 17144 return 0; 17145 } 17146 if ((localtmp = strstr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 17147 char lhost[80], lport[80]; 17148 memset(lhost, 0, sizeof(lhost)); 17149 memset(lport, 0, sizeof(lport)); 17150 localtmp++; 17151 /* This is okey because lhost and lport are as big as tmp */ 17152 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 17153 if (ast_strlen_zero(lhost)) { 17154 ast_log(LOG_ERROR, "Can't find the host address\n"); 17155 return 0; 17156 } 17157 host = ast_strdupa(lhost); 17158 if (!ast_strlen_zero(lport)) { 17159 port = ast_strdupa(lport); 17160 } 17161 } 17162 } 17163 17164 sip_alreadygone(p); 17165 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 17166 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 17167 17168 sip_scheddestroy(p, 32000); /* Make sure we stop send this reply. */ 17169 17170 return 0; 17171 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
Transfer SIP call.
Definition at line 3646 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().
03647 { 03648 struct sip_pvt *p = ast->tech_pvt; 03649 int res; 03650 03651 if (dest == NULL) /* functions below do not take a NULL */ 03652 dest = ""; 03653 ast_mutex_lock(&p->lock); 03654 if (ast->_state == AST_STATE_RING) 03655 res = sip_sipredirect(p, dest); 03656 else 03657 res = transmit_refer(p, dest); 03658 ast_mutex_unlock(&p->lock); 03659 return res; 03660 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 3479 of file chan_sip.c.
References ast_channel::_state, ast_backtrace(), AST_FORMAT_AUDIO_MASK, ast_frame_dump(), AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), sip_pvt::flags, ast_frame::frametype, sip_pvt::initreq, sip_pvt::lastrtptx, sip_pvt::lock, 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.
03480 { 03481 struct sip_pvt *p = ast->tech_pvt; 03482 int res = 0; 03483 03484 switch (frame->frametype) { 03485 case AST_FRAME_VOICE: 03486 if (!(frame->subclass & ast->nativeformats)) { 03487 char s1[512], s2[512], s3[512]; 03488 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n", 03489 frame->subclass, 03490 ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK), 03491 ast->nativeformats & AST_FORMAT_AUDIO_MASK, 03492 ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat), 03493 ast->readformat, 03494 ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat), 03495 ast->writeformat); 03496 ast_frame_dump(ast->name, frame, "<<"); 03497 ast_backtrace(); 03498 return 0; 03499 } 03500 if (p) { 03501 ast_mutex_lock(&p->lock); 03502 if (p->rtp) { 03503 /* If channel is not up, activate early media session */ 03504 if ((ast->_state != AST_STATE_UP) && 03505 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03506 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03507 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03508 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03509 } 03510 p->lastrtptx = time(NULL); 03511 res = ast_rtp_write(p->rtp, frame); 03512 } 03513 ast_mutex_unlock(&p->lock); 03514 } 03515 break; 03516 case AST_FRAME_VIDEO: 03517 if (p) { 03518 ast_mutex_lock(&p->lock); 03519 if (p->vrtp) { 03520 /* Activate video early media */ 03521 if ((ast->_state != AST_STATE_UP) && 03522 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03523 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03524 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03525 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03526 } 03527 p->lastrtptx = time(NULL); 03528 res = ast_rtp_write(p->vrtp, frame); 03529 } 03530 ast_mutex_unlock(&p->lock); 03531 } 03532 break; 03533 case AST_FRAME_IMAGE: 03534 return 0; 03535 break; 03536 case AST_FRAME_MODEM: 03537 if (p) { 03538 ast_mutex_lock(&p->lock); 03539 /* UDPTL requires two-way communication, so early media is not needed here. 03540 we simply forget the frames if we get modem frames before the bridge is up. 03541 Fax will re-transmit. 03542 */ 03543 if (p->udptl && ast->_state == AST_STATE_UP) 03544 res = ast_udptl_write(p->udptl, frame); 03545 ast_mutex_unlock(&p->lock); 03546 } 03547 break; 03548 default: 03549 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 03550 return 0; 03551 } 03552 03553 return res; 03554 }
static int sipsock_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Read data from SIP socket.
Definition at line 14859 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_update_use_count(), ast_verbose(), find_call(), find_sip_method(), sip_pvt::flags, get_header(), handle_request(), len, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, lws2sws(), option_debug, sip_pvt::owner, parse_request(), sip_pvt::recv, S_OR, SIP_ACK, sip_debug_test_addr(), SIP_NO_HISTORY, SIP_PKT_DEBUG, sipsock, and transmit_response().
Referenced by do_monitor().
14860 { 14861 struct sip_request req; 14862 struct sockaddr_in sin = { 0, }; 14863 struct sip_pvt *p; 14864 int res; 14865 socklen_t len = sizeof(sin); 14866 int nounlock; 14867 int recount = 0; 14868 int lockretry; 14869 14870 memset(&req, 0, sizeof(req)); 14871 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 14872 if (res < 0) { 14873 #if !defined(__FreeBSD__) 14874 if (errno == EAGAIN) 14875 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 14876 else 14877 #endif 14878 if (errno != ECONNREFUSED) 14879 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 14880 return 1; 14881 } 14882 if (option_debug && res == sizeof(req.data)) { 14883 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 14884 req.data[sizeof(req.data) - 1] = '\0'; 14885 } else 14886 req.data[res] = '\0'; 14887 req.len = res; 14888 if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */ 14889 ast_set_flag(&req, SIP_PKT_DEBUG); 14890 if (pedanticsipchecking) 14891 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 14892 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 14893 ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data); 14894 14895 parse_request(&req); 14896 req.method = find_sip_method(req.rlPart1); 14897 14898 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 14899 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 14900 14901 if (req.headers < 2) /* Must have at least two headers */ 14902 return 1; 14903 14904 /* Process request, with netlock held, and with usual deadlock avoidance */ 14905 for (lockretry = 100; lockretry > 0; lockretry--) { 14906 ast_mutex_lock(&netlock); 14907 14908 /* Find the active SIP dialog or create a new one */ 14909 p = find_call(&req, &sin, req.method); /* returns p locked */ 14910 if (p == NULL) { 14911 if (option_debug) 14912 ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len); 14913 ast_mutex_unlock(&netlock); 14914 return 1; 14915 } 14916 /* Go ahead and lock the owner if it has one -- we may need it */ 14917 /* becaues this is deadlock-prone, we need to try and unlock if failed */ 14918 if (!p->owner || !ast_channel_trylock(p->owner)) 14919 break; /* locking succeeded */ 14920 if (option_debug) 14921 ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid); 14922 ast_mutex_unlock(&p->lock); 14923 ast_mutex_unlock(&netlock); 14924 /* Sleep for a very short amount of time */ 14925 usleep(1); 14926 } 14927 p->recv = sin; 14928 14929 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */ 14930 append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2); 14931 14932 if (!lockretry) { 14933 if (p->owner) 14934 ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", S_OR(p->owner->name, "- no channel name ??? - ")); 14935 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 14936 if (req.method != SIP_ACK) 14937 transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */ 14938 /* XXX We could add retry-after to make sure they come back */ 14939 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 14940 return 1; 14941 } 14942 nounlock = 0; 14943 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 14944 /* Request failed */ 14945 if (option_debug) 14946 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 14947 } 14948 14949 if (p->owner && !nounlock) 14950 ast_channel_unlock(p->owner); 14951 ast_mutex_unlock(&p->lock); 14952 ast_mutex_unlock(&netlock); 14953 if (recount) 14954 ast_update_use_count(); 14955 14956 return 1; 14957 }
static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 12197 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(), and handle_response().
12198 { 12199 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12200 if (p->rtp) 12201 ast_rtp_stop(p->rtp); 12202 if (p->vrtp) 12203 ast_rtp_stop(p->vrtp); 12204 if (p->udptl) 12205 ast_udptl_stop(p->udptl); 12206 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 10414 of file chan_sip.c.
References subscription_types, and type.
Referenced by sip_show_channel().
10415 { 10416 int i; 10417 10418 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10419 if (subscription_types[i].type == subtype) { 10420 return subscription_types[i].text; 10421 } 10422 } 10423 return subscription_types[0].text; 10424 }
static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 5982 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().
05983 { 05984 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 05985 05986 if (maxrate & T38FAX_RATE_14400) { 05987 if (option_debug > 1) 05988 ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n"); 05989 return 14400; 05990 } else if (maxrate & T38FAX_RATE_12000) { 05991 if (option_debug > 1) 05992 ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n"); 05993 return 12000; 05994 } else if (maxrate & T38FAX_RATE_9600) { 05995 if (option_debug > 1) 05996 ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n"); 05997 return 9600; 05998 } else if (maxrate & T38FAX_RATE_7200) { 05999 if (option_debug > 1) 06000 ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n"); 06001 return 7200; 06002 } else if (maxrate & T38FAX_RATE_4800) { 06003 if (option_debug > 1) 06004 ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n"); 06005 return 4800; 06006 } else if (maxrate & T38FAX_RATE_2400) { 06007 if (option_debug > 1) 06008 ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n"); 06009 return 2400; 06010 } else { 06011 if (option_debug > 1) 06012 ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n"); 06013 return 0; 06014 } 06015 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 15931 of file chan_sip.c.
References ast_calloc, ast_set_flag, ASTOBJ_INIT, default_prefs, reg_source_db(), set_peer_defaults(), SIP_PAGE2_DYNAMIC, and SIP_PAGE2_SELFDESTRUCT.
Referenced by register_verify().
15932 { 15933 struct sip_peer *peer; 15934 15935 if (!(peer = ast_calloc(1, sizeof(*peer)))) 15936 return NULL; 15937 15938 apeerobjs++; 15939 ASTOBJ_INIT(peer); 15940 set_peer_defaults(peer); 15941 15942 ast_copy_string(peer->name, name, sizeof(peer->name)); 15943 15944 ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT); 15945 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 15946 peer->prefs = default_prefs; 15947 reg_source_db(peer); 15948 15949 return peer; 15950 }
static void temp_pvt_cleanup | ( | void * | ) | [static] |
Definition at line 5761 of file chan_sip.c.
References ast_string_field_free_pools, and free.
05762 { 05763 struct sip_pvt *p = data; 05764 05765 ast_string_field_free_pools(p); 05766 05767 free(data); 05768 }
static char * transfermode2str | ( | enum transfermodes | mode | ) | const [static] |
Convert transfer mode to text string.
Definition at line 9418 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().
09419 { 09420 if (mode == TRANSFER_OPENFORALL) 09421 return "open"; 09422 else if (mode == TRANSFER_CLOSED) 09423 return "closed"; 09424 return "strict"; 09425 }
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 8260 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().
08261 { 08262 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08263 transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0); 08264 }
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 7504 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
07505 { 07506 struct sip_request req; 07507 07508 reqprep(&req, p, SIP_INFO, 0, 1); 07509 add_digit(&req, digit, duration); 07510 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07511 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 7514 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
07515 { 07516 struct sip_request req; 07517 07518 reqprep(&req, p, SIP_INFO, 0, 1); 07519 add_vidupdate(&req); 07520 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07521 }
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 6782 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().
06783 { 06784 struct sip_request req; 06785 06786 req.method = sipmethod; 06787 if (init) { /* Seems like init always is 2 */ 06788 /* Bump branch even on initial requests */ 06789 p->branch ^= ast_random(); 06790 build_via(p); 06791 if (init > 1) 06792 initreqprep(&req, p, sipmethod); 06793 else 06794 reqprep(&req, p, sipmethod, 0, 1); 06795 } else 06796 reqprep(&req, p, sipmethod, 0, 1); 06797 06798 if (p->options && p->options->auth) 06799 add_header(&req, p->options->authheader, p->options->auth); 06800 append_date(&req); 06801 if (sipmethod == SIP_REFER) { /* Call transfer */ 06802 if (p->refer) { 06803 char buf[BUFSIZ]; 06804 if (!ast_strlen_zero(p->refer->refer_to)) 06805 add_header(&req, "Refer-To", p->refer->refer_to); 06806 if (!ast_strlen_zero(p->refer->referred_by)) { 06807 sprintf(buf, "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 06808 add_header(&req, "Referred-By", buf); 06809 } 06810 } 06811 } 06812 /* This new INVITE is part of an attended transfer. Make sure that the 06813 other end knows and replace the current call with this new call */ 06814 if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) { 06815 add_header(&req, "Replaces", p->options->replaces); 06816 add_header(&req, "Require", "replaces"); 06817 } 06818 06819 add_header(&req, "Allow", ALLOWED_METHODS); 06820 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06821 if (p->options && p->options->addsipheaders && p->owner) { 06822 struct ast_channel *ast = p->owner; /* The owner channel */ 06823 struct varshead *headp = &ast->varshead; 06824 06825 if (!headp) 06826 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 06827 else { 06828 const struct ast_var_t *current; 06829 AST_LIST_TRAVERSE(headp, current, entries) { 06830 /* SIPADDHEADER: Add SIP header to outgoing call */ 06831 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 06832 char *content, *end; 06833 const char *header = ast_var_value(current); 06834 char *headdup = ast_strdupa(header); 06835 06836 /* Strip of the starting " (if it's there) */ 06837 if (*headdup == '"') 06838 headdup++; 06839 if ((content = strchr(headdup, ':'))) { 06840 *content++ = '\0'; 06841 content = ast_skip_blanks(content); /* Skip white space */ 06842 /* Strip the ending " (if it's there) */ 06843 end = content + strlen(content) -1; 06844 if (*end == '"') 06845 *end = '\0'; 06846 06847 add_header(&req, headdup, content); 06848 if (sipdebug) 06849 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 06850 } 06851 } 06852 } 06853 } 06854 } 06855 if (sdp) { 06856 if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) { 06857 ast_udptl_offered_from_local(p->udptl, 1); 06858 if (option_debug) 06859 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 06860 add_t38_sdp(&req, p); 06861 } else if (p->rtp) 06862 add_sdp(&req, p); 06863 } else { 06864 add_header_contentLength(&req, 0); 06865 } 06866 06867 if (!p->initreq.headers) 06868 initialize_initreq(p, &req); 06869 p->lastinvite = p->ocseq; 06870 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 06871 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 7412 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().
07413 { 07414 struct sip_request req; 07415 07416 reqprep(&req, p, SIP_MESSAGE, 0, 1); 07417 add_text(&req, text); 07418 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07419 }
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 7052 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().
07053 { 07054 struct sip_request req; 07055 char tmp[500]; 07056 char *t = tmp; 07057 size_t maxbytes = sizeof(tmp); 07058 07059 initreqprep(&req, p, SIP_NOTIFY); 07060 add_header(&req, "Event", "message-summary"); 07061 add_header(&req, "Content-Type", default_notifymime); 07062 07063 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 07064 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 07065 S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 07066 /* Cisco has a bug in the SIP stack where it can't accept the 07067 (0/0) notification. This can temporarily be disabled in 07068 sip.conf with the "buggymwi" option */ 07069 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)")); 07070 07071 if (p->subscribed) { 07072 if (p->expiry) 07073 add_header(&req, "Subscription-State", "active"); 07074 else /* Expired */ 07075 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07076 } 07077 07078 if (t > tmp + sizeof(tmp)) 07079 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07080 07081 add_header_contentLength(&req, strlen(tmp)); 07082 add_line(&req, tmp); 07083 07084 if (!p->initreq.headers) 07085 initialize_initreq(p, &req); 07086 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07087 }
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 7098 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().
07099 { 07100 struct sip_request req; 07101 char tmp[BUFSIZ/2]; 07102 07103 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07104 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 07105 add_header(&req, "Event", tmp); 07106 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 07107 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 07108 add_header(&req, "Allow", ALLOWED_METHODS); 07109 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07110 07111 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 07112 add_header_contentLength(&req, strlen(tmp)); 07113 add_line(&req, tmp); 07114 07115 if (!p->initreq.headers) 07116 initialize_initreq(p, &req); 07117 07118 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07119 }
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 7433 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().
07434 { 07435 struct sip_request req = { 07436 .headers = 0, 07437 }; 07438 char from[256]; 07439 const char *of; 07440 char *c; 07441 char referto[256]; 07442 char *ttag, *ftag; 07443 char *theirtag = ast_strdupa(p->theirtag); 07444 07445 if (option_debug || sipdebug) 07446 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 07447 07448 /* Are we transfering an inbound or outbound call ? */ 07449 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07450 of = get_header(&p->initreq, "To"); 07451 ttag = theirtag; 07452 ftag = p->tag; 07453 } else { 07454 of = get_header(&p->initreq, "From"); 07455 ftag = theirtag; 07456 ttag = p->tag; 07457 } 07458 07459 ast_copy_string(from, of, sizeof(from)); 07460 of = get_in_brackets(from); 07461 ast_string_field_set(p, from, of); 07462 if (strncmp(of, "sip:", 4)) 07463 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 07464 else 07465 of += 4; 07466 /* Get just the username part */ 07467 if ((c = strchr(dest, '@'))) 07468 c = NULL; 07469 else if ((c = strchr(of, '@'))) 07470 *c++ = '\0'; 07471 if (c) 07472 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 07473 else 07474 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 07475 07476 /* save in case we get 407 challenge */ 07477 sip_refer_allocate(p); 07478 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 07479 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 07480 p->refer->status = REFER_SENT; /* Set refer status */ 07481 07482 reqprep(&req, p, SIP_REFER, 0, 1); 07483 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07484 07485 add_header(&req, "Refer-To", referto); 07486 add_header(&req, "Allow", ALLOWED_METHODS); 07487 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07488 if (!ast_strlen_zero(p->our_contact)) 07489 add_header(&req, "Referred-By", p->our_contact); 07490 07491 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07492 /* We should propably wait for a NOTIFY here until we ack the transfer */ 07493 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 07494 07495 /*! \todo In theory, we should hang around and wait for a reply, before 07496 returning to the dial plan here. Don't know really how that would 07497 affect the transfer() app or the pbx, but, well, to make this 07498 useful we should have a STATUS code on transfer(). 07499 */ 07500 }
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 7221 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_registry::portno, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sched, send_request(), sip_alloc(), sip_debug_test_pvt(), sip_destroy(), sip_methods, SIP_NO_HISTORY, SIP_OUTGOING, sip_reg_timeout(), SIP_REGISTER, sipdebug, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_registry::timeout, TRUE, username, and XMIT_CRITICAL.
Referenced by __sip_do_register(), do_register_auth(), and sip_reg_timeout().
07222 { 07223 struct sip_request req; 07224 char from[256]; 07225 char to[256]; 07226 char tmp[80]; 07227 char addr[80]; 07228 struct sip_pvt *p; 07229 07230 /* exit if we are already in process with this registrar ?*/ 07231 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 07232 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 07233 return 0; 07234 } 07235 07236 if (r->call) { /* We have a registration */ 07237 if (!auth) { 07238 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 07239 return 0; 07240 } else { 07241 p = r->call; 07242 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 07243 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 07244 } 07245 } else { 07246 /* Build callid for registration if we haven't registered before */ 07247 if (!r->callid_valid) { 07248 build_callid_registry(r, __ourip, default_fromdomain); 07249 r->callid_valid = TRUE; 07250 } 07251 /* Allocate SIP packet for registration */ 07252 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) { 07253 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 07254 return 0; 07255 } 07256 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07257 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 07258 /* Find address to hostname */ 07259 if (create_addr(p, r->hostname)) { 07260 /* we have what we hope is a temporary network error, 07261 * probably DNS. We need to reschedule a registration try */ 07262 sip_destroy(p); 07263 if (r->timeout > -1) { 07264 ast_sched_del(sched, r->timeout); 07265 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 07266 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 07267 } else { 07268 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 07269 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); 07270 } 07271 r->regattempts++; 07272 return 0; 07273 } 07274 /* Copy back Call-ID in case create_addr changed it */ 07275 ast_string_field_set(r, callid, p->callid); 07276 if (r->portno) 07277 p->sa.sin_port = htons(r->portno); 07278 else /* Set registry port to the port set from the peer definition/srv or default */ 07279 r->portno = ntohs(p->sa.sin_port); 07280 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 07281 r->call=p; /* Save pointer to SIP packet */ 07282 p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ 07283 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 07284 ast_string_field_set(p, peersecret, r->secret); 07285 if (!ast_strlen_zero(r->md5secret)) 07286 ast_string_field_set(p, peermd5secret, r->md5secret); 07287 /* User name in this realm 07288 - if authuser is set, use that, otherwise use username */ 07289 if (!ast_strlen_zero(r->authuser)) { 07290 ast_string_field_set(p, peername, r->authuser); 07291 ast_string_field_set(p, authname, r->authuser); 07292 } else if (!ast_strlen_zero(r->username)) { 07293 ast_string_field_set(p, peername, r->username); 07294 ast_string_field_set(p, authname, r->username); 07295 ast_string_field_set(p, fromuser, r->username); 07296 } 07297 if (!ast_strlen_zero(r->username)) 07298 ast_string_field_set(p, username, r->username); 07299 /* Save extension in packet */ 07300 ast_string_field_set(p, exten, r->contact); 07301 07302 /* 07303 check which address we should use in our contact header 07304 based on whether the remote host is on the external or 07305 internal network so we can register through nat 07306 */ 07307 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 07308 p->ourip = bindaddr.sin_addr; 07309 build_contact(p); 07310 } 07311 07312 /* set up a timeout */ 07313 if (auth == NULL) { 07314 if (r->timeout > -1) { 07315 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 07316 ast_sched_del(sched, r->timeout); 07317 } 07318 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07319 if (option_debug) 07320 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 07321 } 07322 07323 if (strchr(r->username, '@')) { 07324 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 07325 if (!ast_strlen_zero(p->theirtag)) 07326 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 07327 else 07328 snprintf(to, sizeof(to), "<sip:%s>", r->username); 07329 } else { 07330 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 07331 if (!ast_strlen_zero(p->theirtag)) 07332 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 07333 else 07334 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 07335 } 07336 07337 /* Fromdomain is what we are registering to, regardless of actual 07338 host name from SRV */ 07339 if (!ast_strlen_zero(p->fromdomain)) { 07340 if (r->portno && r->portno != STANDARD_SIP_PORT) 07341 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 07342 else 07343 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 07344 } else { 07345 if (r->portno && r->portno != STANDARD_SIP_PORT) 07346 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 07347 else 07348 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 07349 } 07350 ast_string_field_set(p, uri, addr); 07351 07352 p->branch ^= ast_random(); 07353 07354 init_req(&req, sipmethod, addr); 07355 07356 /* Add to CSEQ */ 07357 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 07358 p->ocseq = r->ocseq; 07359 07360 build_via(p); 07361 add_header(&req, "Via", p->via); 07362 add_header(&req, "From", from); 07363 add_header(&req, "To", to); 07364 add_header(&req, "Call-ID", p->callid); 07365 add_header(&req, "CSeq", tmp); 07366 if (!ast_strlen_zero(global_useragent)) 07367 add_header(&req, "User-Agent", global_useragent); 07368 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07369 07370 07371 if (auth) /* Add auth header */ 07372 add_header(&req, authheader, auth); 07373 else if (!ast_strlen_zero(r->nonce)) { 07374 char digest[1024]; 07375 07376 /* We have auth data to reuse, build a digest header! */ 07377 if (sipdebug) 07378 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 07379 ast_string_field_set(p, realm, r->realm); 07380 ast_string_field_set(p, nonce, r->nonce); 07381 ast_string_field_set(p, domain, r->domain); 07382 ast_string_field_set(p, opaque, r->opaque); 07383 ast_string_field_set(p, qop, r->qop); 07384 r->noncecount++; 07385 p->noncecount = r->noncecount; 07386 07387 memset(digest,0,sizeof(digest)); 07388 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 07389 add_header(&req, "Authorization", digest); 07390 else 07391 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 07392 07393 } 07394 07395 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 07396 add_header(&req, "Expires", tmp); 07397 add_header(&req, "Contact", p->our_contact); 07398 add_header(&req, "Event", "registration"); 07399 add_header_contentLength(&req, 0); 07400 07401 initialize_initreq(p, &req); 07402 if (sip_debug_test_pvt(p)) 07403 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 07404 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 07405 r->regattempts++; /* Another attempt */ 07406 if (option_debug > 3) 07407 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 07408 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07409 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with SDP.
Definition at line 6502 of file chan_sip.c.
References add_header(), add_sdp(), ALLOWED_METHODS, append_history, ast_set_flag, ast_test_flag, sip_pvt::flags, initialize_initreq(), reqprep(), send_request(), SIP_INVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, sipdebug, SUPPORTED_EXTENSIONS, and XMIT_CRITICAL.
Referenced by check_pendings(), and sip_set_rtp_peer().
06503 { 06504 struct sip_request req; 06505 06506 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06507 06508 add_header(&req, "Allow", ALLOWED_METHODS); 06509 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06510 if (sipdebug) 06511 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 06512 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 06513 append_history(p, "ReInv", "Re-invite sent"); 06514 add_sdp(&req, p); 06515 /* Use this as the basis */ 06516 initialize_initreq(p, &req); 06517 p->lastinvite = p->ocseq; 06518 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06519 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06520 }
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 6526 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().
06527 { 06528 struct sip_request req; 06529 06530 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06531 06532 add_header(&req, "Allow", ALLOWED_METHODS); 06533 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06534 if (sipdebug) 06535 add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)"); 06536 ast_udptl_offered_from_local(p->udptl, 1); 06537 add_t38_sdp(&req, p); 06538 /* Use this as the basis */ 06539 initialize_initreq(p, &req); 06540 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06541 p->lastinvite = p->ocseq; 06542 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06543 }
static int transmit_request | ( | struct sip_pvt * | p, | |
int | sipmethod, | |||
int | inc, | |||
enum xmittype | reliable, | |||
int | newbranch | |||
) | [static] |
Transmit generic SIP request.
Definition at line 7524 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().
07525 { 07526 struct sip_request resp; 07527 07528 if (sipmethod == SIP_ACK) 07529 p->invitestate = INV_CONFIRMED; 07530 07531 reqprep(&resp, p, sipmethod, seqno, newbranch); 07532 add_header_contentLength(&resp, 0); 07533 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07534 }
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 7537 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().
07538 { 07539 struct sip_request resp; 07540 07541 reqprep(&resp, p, sipmethod, seqno, newbranch); 07542 if (!ast_strlen_zero(p->realm)) { 07543 char digest[1024]; 07544 07545 memset(digest, 0, sizeof(digest)); 07546 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 07547 if (p->options && p->options->auth_type == PROXY_AUTH) 07548 add_header(&resp, "Proxy-Authorization", digest); 07549 else if (p->options && p->options->auth_type == WWW_AUTH) 07550 add_header(&resp, "Authorization", digest); 07551 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 07552 add_header(&resp, "Proxy-Authorization", digest); 07553 } else 07554 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 07555 } 07556 /* If we are hanging up and know a cause for that, send it in clear text to make 07557 debugging easier. */ 07558 if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) { 07559 char buf[10]; 07560 07561 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 07562 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 07563 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 07564 } 07565 07566 add_header_contentLength(&resp, 0); 07567 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07568 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 5821 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
05822 { 05823 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 05824 }
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 5840 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().
05841 { 05842 return __transmit_response(p, msg, req, XMIT_CRITICAL); 05843 }
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 5771 of file chan_sip.c.
References __ourip, __transmit_response(), ast_copy_flags, ast_log(), ast_random(), ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_free_all, ast_string_field_init, ast_string_field_set, ast_test_flag, build_via(), do_setnat(), global_flags, INITIAL_CSEQ, LOG_NOTICE, make_our_tag(), SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, and XMIT_UNRELIABLE.
05772 { 05773 struct sip_pvt *p = NULL; 05774 05775 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 05776 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 05777 return -1; 05778 } 05779 05780 /* if the structure was just allocated, initialize it */ 05781 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 05782 ast_set_flag(&p->flags[0], SIP_NO_HISTORY); 05783 if (ast_string_field_init(p, 512)) 05784 return -1; 05785 } 05786 05787 /* Initialize the bare minimum */ 05788 p->method = intended_method; 05789 05790 if (sin) { 05791 p->sa = *sin; 05792 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 05793 p->ourip = __ourip; 05794 } else 05795 p->ourip = __ourip; 05796 05797 p->branch = ast_random(); 05798 make_our_tag(p->tag, sizeof(p->tag)); 05799 p->ocseq = INITIAL_CSEQ; 05800 05801 if (useglobal_nat && sin) { 05802 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 05803 p->recv = *sin; 05804 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 05805 } 05806 05807 ast_string_field_set(p, fromdomain, default_fromdomain); 05808 build_via(p); 05809 ast_string_field_set(p, callid, callid); 05810 05811 /* Use this temporary pvt structure to send the message */ 05812 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 05813 05814 /* Free the string fields, but not the pool space */ 05815 ast_string_field_free_all(p); 05816 05817 return 0; 05818 }
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 5868 of file chan_sip.c.
References add_header(), add_header_contentLength(), respprep(), and send_response().
Referenced by handle_request(), and handle_request_options().
05869 { 05870 struct sip_request resp; 05871 respprep(&resp, p, msg, req); 05872 add_header(&resp, "Accept", "application/sdp"); 05873 add_header_contentLength(&resp, 0); 05874 return send_response(p, &resp, reliable, 0); 05875 }
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 5878 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().
05879 { 05880 struct sip_request resp; 05881 char tmp[512]; 05882 int seqno = 0; 05883 05884 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 05885 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 05886 return -1; 05887 } 05888 /* Stale means that they sent us correct authentication, but 05889 based it on an old challenge (nonce) */ 05890 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 05891 respprep(&resp, p, msg, req); 05892 add_header(&resp, header, tmp); 05893 add_header_contentLength(&resp, 0); 05894 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 05895 return send_response(p, &resp, reliable, seqno); 05896 }
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 5858 of file chan_sip.c.
References add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
05859 { 05860 struct sip_request resp; 05861 respprep(&resp, p, msg, req); 05862 append_date(&resp); 05863 add_header_contentLength(&resp, 0); 05864 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 05865 }
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 6431 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().
06432 { 06433 struct sip_request resp; 06434 int seqno; 06435 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06436 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06437 return -1; 06438 } 06439 respprep(&resp, p, msg, req); 06440 if (p->rtp) { 06441 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06442 if (option_debug) 06443 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 06444 ast_rtp_codec_setpref(p->rtp, &p->prefs); 06445 } 06446 try_suggested_sip_codec(p); 06447 add_sdp(&resp, p); 06448 } else 06449 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 06450 if (reliable && !p->pendinginvite) 06451 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06452 return send_response(p, &resp, reliable, seqno); 06453 }
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 6393 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().
06394 { 06395 struct sip_request resp; 06396 int seqno; 06397 06398 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06399 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06400 return -1; 06401 } 06402 respprep(&resp, p, msg, req); 06403 if (p->udptl) { 06404 ast_udptl_offered_from_local(p->udptl, 0); 06405 add_t38_sdp(&resp, p); 06406 } else 06407 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 06408 if (retrans && !p->pendinginvite) 06409 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06410 return send_response(p, &resp, retrans, seqno); 06411 }
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 5827 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
05828 { 05829 struct sip_request resp; 05830 respprep(&resp, p, msg, req); 05831 append_date(&resp); 05832 add_header(&resp, "Unsupported", unsupported); 05833 add_header_contentLength(&resp, 0); 05834 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 05835 }
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 7090 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().
07091 { 07092 if (!p->initreq.headers) /* Initialize first request before sending */ 07093 initialize_initreq(p, req); 07094 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 07095 }
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 6874 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), ast_log(), AST_MAX_EXTENSION, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, sip_pvt::expiry, find_subscription_type(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, 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().
06875 { 06876 char tmp[4000], from[256], to[256]; 06877 char *t = tmp, *c, *mfrom, *mto; 06878 size_t maxbytes = sizeof(tmp); 06879 struct sip_request req; 06880 char hint[AST_MAX_EXTENSION]; 06881 char *statestring = "terminated"; 06882 const struct cfsubscription_types *subscriptiontype; 06883 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 06884 char *pidfstate = "--"; 06885 char *pidfnote= "Ready"; 06886 06887 memset(from, 0, sizeof(from)); 06888 memset(to, 0, sizeof(to)); 06889 memset(tmp, 0, sizeof(tmp)); 06890 06891 switch (state) { 06892 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 06893 statestring = (global_notifyringing) ? "early" : "confirmed"; 06894 local_state = NOTIFY_INUSE; 06895 pidfstate = "busy"; 06896 pidfnote = "Ringing"; 06897 break; 06898 case AST_EXTENSION_RINGING: 06899 statestring = "early"; 06900 local_state = NOTIFY_INUSE; 06901 pidfstate = "busy"; 06902 pidfnote = "Ringing"; 06903 break; 06904 case AST_EXTENSION_INUSE: 06905 statestring = "confirmed"; 06906 local_state = NOTIFY_INUSE; 06907 pidfstate = "busy"; 06908 pidfnote = "On the phone"; 06909 break; 06910 case AST_EXTENSION_BUSY: 06911 statestring = "confirmed"; 06912 local_state = NOTIFY_CLOSED; 06913 pidfstate = "busy"; 06914 pidfnote = "On the phone"; 06915 break; 06916 case AST_EXTENSION_UNAVAILABLE: 06917 statestring = "terminated"; 06918 local_state = NOTIFY_CLOSED; 06919 pidfstate = "away"; 06920 pidfnote = "Unavailable"; 06921 break; 06922 case AST_EXTENSION_ONHOLD: 06923 statestring = "confirmed"; 06924 local_state = NOTIFY_INUSE; 06925 pidfstate = "busy"; 06926 pidfnote = "On Hold"; 06927 break; 06928 case AST_EXTENSION_NOT_INUSE: 06929 default: 06930 /* Default setting */ 06931 break; 06932 } 06933 06934 subscriptiontype = find_subscription_type(p->subscribed); 06935 06936 /* Check which device/devices we are watching and if they are registered */ 06937 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 06938 char *hint2 = hint, *individual_hint = NULL; 06939 while ((individual_hint = strsep(&hint2, "&"))) { 06940 /* If they are not registered, we will override notification and show no availability */ 06941 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) { 06942 local_state = NOTIFY_CLOSED; 06943 pidfstate = "away"; 06944 pidfnote = "Not online"; 06945 } 06946 } 06947 } 06948 06949 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 06950 c = get_in_brackets(from); 06951 if (strncmp(c, "sip:", 4)) { 06952 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 06953 return -1; 06954 } 06955 mfrom = strsep(&c, ";"); /* trim ; and beyond */ 06956 06957 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 06958 c = get_in_brackets(to); 06959 if (strncmp(c, "sip:", 4)) { 06960 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 06961 return -1; 06962 } 06963 mto = strsep(&c, ";"); /* trim ; and beyond */ 06964 06965 reqprep(&req, p, SIP_NOTIFY, 0, 1); 06966 06967 06968 add_header(&req, "Event", subscriptiontype->event); 06969 add_header(&req, "Content-Type", subscriptiontype->mediatype); 06970 switch(state) { 06971 case AST_EXTENSION_DEACTIVATED: 06972 if (timeout) 06973 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 06974 else { 06975 add_header(&req, "Subscription-State", "terminated;reason=probation"); 06976 add_header(&req, "Retry-After", "60"); 06977 } 06978 break; 06979 case AST_EXTENSION_REMOVED: 06980 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 06981 break; 06982 default: 06983 if (p->expiry) 06984 add_header(&req, "Subscription-State", "active"); 06985 else /* Expired */ 06986 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 06987 } 06988 switch (p->subscribed) { 06989 case XPIDF_XML: 06990 case CPIM_PIDF_XML: 06991 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 06992 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 06993 ast_build_string(&t, &maxbytes, "<presence>\n"); 06994 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 06995 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 06996 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 06997 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 06998 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 06999 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 07000 break; 07001 case PIDF_XML: /* Eyebeam supports this format */ 07002 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 07003 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); 07004 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 07005 if (pidfstate[0] != '-') 07006 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 07007 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 07008 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 07009 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 07010 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 07011 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 07012 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 07013 else 07014 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 07015 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 07016 break; 07017 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 07018 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07019 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); 07020 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 07021 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 07022 else 07023 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 07024 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 07025 if (state == AST_EXTENSION_ONHOLD) { 07026 ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n" 07027 "<param pname=\"+sip.rendering\" pvalue=\"no\">\n" 07028 "</target>\n</local>\n", mto); 07029 } 07030 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 07031 break; 07032 case NONE: 07033 default: 07034 break; 07035 } 07036 07037 if (t > tmp + sizeof(tmp)) 07038 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07039 07040 add_header_contentLength(&req, strlen(tmp)); 07041 add_line(&req, tmp); 07042 07043 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07044 }
static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 3430 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().
03431 { 03432 int fmt; 03433 const char *codec; 03434 03435 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 03436 if (!codec) 03437 return; 03438 03439 fmt = ast_getformatbyname(codec); 03440 if (fmt) { 03441 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 03442 if (p->jointcapability & fmt) { 03443 p->jointcapability &= fmt; 03444 p->capability &= fmt; 03445 } else 03446 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 03447 } else 03448 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 03449 return; 03450 }
static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 17474 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_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_udptl_proto_unregister(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, checksipdomain_function, clear_realm_authentication(), clear_sip_domains(), cli_sip, iflist, localaddr, sip_pvt::next, sip_pvt::owner, peerl, regl, sched, sched_context_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_header_function, sip_registry_destroy(), sip_rtp, sip_tech, sip_udptl, sipchaninfo_function, sippeer_function, sipsock, TRUE, and userl.
17475 { 17476 struct sip_pvt *p, *pl; 17477 17478 /* First, take us out of the channel type list */ 17479 ast_channel_unregister(&sip_tech); 17480 17481 /* Unregister dial plan functions */ 17482 ast_custom_function_unregister(&sipchaninfo_function); 17483 ast_custom_function_unregister(&sippeer_function); 17484 ast_custom_function_unregister(&sip_header_function); 17485 ast_custom_function_unregister(&checksipdomain_function); 17486 17487 /* Unregister dial plan applications */ 17488 ast_unregister_application(app_dtmfmode); 17489 ast_unregister_application(app_sipaddheader); 17490 17491 /* Unregister CLI commands */ 17492 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 17493 17494 /* Disconnect from the RTP subsystem */ 17495 ast_rtp_proto_unregister(&sip_rtp); 17496 17497 /* Disconnect from UDPTL */ 17498 ast_udptl_proto_unregister(&sip_udptl); 17499 17500 /* Unregister AMI actions */ 17501 ast_manager_unregister("SIPpeers"); 17502 ast_manager_unregister("SIPshowpeer"); 17503 17504 ast_mutex_lock(&iflock); 17505 /* Hangup all interfaces if they have an owner */ 17506 for (p = iflist; p ; p = p->next) { 17507 if (p->owner) 17508 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 17509 } 17510 ast_mutex_unlock(&iflock); 17511 17512 ast_mutex_lock(&monlock); 17513 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) { 17514 pthread_cancel(monitor_thread); 17515 pthread_kill(monitor_thread, SIGURG); 17516 pthread_join(monitor_thread, NULL); 17517 } 17518 monitor_thread = AST_PTHREADT_STOP; 17519 ast_mutex_unlock(&monlock); 17520 17521 ast_mutex_lock(&iflock); 17522 /* Destroy all the interfaces and free their memory */ 17523 p = iflist; 17524 while (p) { 17525 pl = p; 17526 p = p->next; 17527 __sip_destroy(pl, TRUE); 17528 } 17529 iflist = NULL; 17530 ast_mutex_unlock(&iflock); 17531 17532 /* Free memory for local network address mask */ 17533 ast_free_ha(localaddr); 17534 17535 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 17536 ASTOBJ_CONTAINER_DESTROY(&userl); 17537 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 17538 ASTOBJ_CONTAINER_DESTROY(&peerl); 17539 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 17540 ASTOBJ_CONTAINER_DESTROY(®l); 17541 17542 clear_realm_authentication(authl); 17543 clear_sip_domains(); 17544 close(sipsock); 17545 sched_context_destroy(sched); 17546 17547 return 0; 17548 }
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 2996 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_peer_hold(), and sipdebug.
Referenced by __sip_destroy(), handle_request_invite(), handle_response_invite(), sip_call(), and sip_hangup().
02997 { 02998 char name[256]; 02999 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 03000 int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL); 03001 struct sip_user *u = NULL; 03002 struct sip_peer *p = NULL; 03003 03004 if (option_debug > 2) 03005 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 03006 /* Test if we need to check call limits, in order to avoid 03007 realtime lookups if we do not need it */ 03008 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT)) 03009 return 0; 03010 03011 ast_copy_string(name, fup->username, sizeof(name)); 03012 03013 /* Check the list of users only for incoming calls */ 03014 if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) { 03015 inuse = &u->inUse; 03016 call_limit = &u->call_limit; 03017 inringing = NULL; 03018 } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1) ) ) { /* Try to find peer */ 03019 inuse = &p->inUse; 03020 call_limit = &p->call_limit; 03021 inringing = &p->inRinging; 03022 ast_copy_string(name, fup->peername, sizeof(name)); 03023 } 03024 if (!p && !u) { 03025 if (option_debug > 1) 03026 ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name); 03027 return 0; 03028 } 03029 03030 switch(event) { 03031 /* incoming and outgoing affects the inUse counter */ 03032 case DEC_CALL_LIMIT: 03033 if ( *inuse > 0 ) { 03034 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 03035 (*inuse)--; 03036 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 03037 } 03038 } else { 03039 *inuse = 0; 03040 } 03041 if (inringing) { 03042 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03043 if (*inringing > 0) 03044 (*inringing)--; 03045 else 03046 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername); 03047 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03048 } 03049 } 03050 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) 03051 sip_peer_hold(fup, 0); 03052 if (option_debug > 1 || sipdebug) { 03053 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 03054 } 03055 break; 03056 03057 case INC_CALL_RINGING: 03058 case INC_CALL_LIMIT: 03059 if (*call_limit > 0 ) { 03060 if (*inuse >= *call_limit) { 03061 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); 03062 if (u) 03063 ASTOBJ_UNREF(u, sip_destroy_user); 03064 else 03065 ASTOBJ_UNREF(p, sip_destroy_peer); 03066 return -1; 03067 } 03068 } 03069 if (inringing && (event == INC_CALL_RINGING)) { 03070 if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03071 (*inringing)++; 03072 ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03073 } 03074 } 03075 /* Continue */ 03076 (*inuse)++; 03077 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 03078 if (option_debug > 1 || sipdebug) { 03079 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 03080 } 03081 break; 03082 03083 case DEC_CALL_RINGING: 03084 if (inringing) { 03085 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03086 if (*inringing > 0) 03087 (*inringing)--; 03088 else 03089 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name); 03090 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03091 } 03092 } 03093 break; 03094 03095 default: 03096 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 03097 } 03098 if (p) { 03099 ast_device_state_changed("SIP/%s", p->name); 03100 ASTOBJ_UNREF(p, sip_destroy_peer); 03101 } else /* u must be set */ 03102 ASTOBJ_UNREF(u, sip_destroy_user); 03103 return 0; 03104 }
static void update_peer | ( | struct sip_peer * | p, | |
int | expiry | |||
) | [static] |
Update peer data in database (if used).
Definition at line 2393 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, sip_peer::fullcontact, global_flags, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_REALTIME, and sip_peer::username.
Referenced by register_verify().
02394 { 02395 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02396 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) && 02397 (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) { 02398 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry); 02399 } 02400 }
struct in_addr __ourip [static] |
Definition at line 1189 of file chan_sip.c.
int allow_external_domains [static] |
Accept calls to external SIP domains?
Definition at line 554 of file chan_sip.c.
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 570 of file chan_sip.c.
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 17013 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 17015 of file chan_sip.c.
Definition at line 1178 of file chan_sip.c.
Referenced by build_reply_digest(), sip_do_reload(), sip_show_settings(), and unload_module().
int autocreatepeer [static] |
Auto creation of peers at registration? Default off.
Definition at line 534 of file chan_sip.c.
struct sockaddr_in bindaddr = { 0, } [static] |
The address we bind to
Definition at line 1183 of file chan_sip.c.
struct ast_custom_function checksipdomain_function [static] |
struct ast_cli_entry cli_sip[] [static] |
struct ast_cli_entry cli_sip_debug_deprecated [static] |
Initial value:
{ { "sip", "debug", NULL }, sip_do_debug_deprecated, "Enable SIP debugging", debug_usage }
Definition at line 17300 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 17305 of file chan_sip.c.
int compactheaders [static] |
send compact sip headers
Definition at line 548 of file chan_sip.c.
const char config[] = "sip.conf" [static] |
Definition at line 222 of file chan_sip.c.
char debug_usage[] [static] |
Definition at line 11316 of file chan_sip.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1192 of file chan_sip.c.
Referenced by sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), and sip_do_debug_peer().
char default_callerid[AST_MAX_EXTENSION] [static] |
Definition at line 514 of file chan_sip.c.
char default_context[AST_MAX_CONTEXT] [static] |
Definition at line 511 of file chan_sip.c.
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 185 of file chan_sip.c.
char default_fromdomain[AST_MAX_EXTENSION] [static] |
Definition at line 515 of file chan_sip.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled.
Definition at line 213 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Definition at line 513 of file chan_sip.c.
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 522 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 519 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 520 of file chan_sip.c.
char default_notifymime[AST_MAX_EXTENSION] [static] |
Definition at line 516 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 523 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 517 of file chan_sip.c.
char default_subscribecontext[AST_MAX_CONTEXT] [static] |
Definition at line 512 of file chan_sip.c.
char default_vmexten[AST_MAX_EXTENSION] [static] |
Definition at line 518 of file chan_sip.c.
char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static] |
Definition at line 17012 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 17018 of file chan_sip.c.
int dumphistory [static] |
Dump history to verbose before destroying SIP dialog
Definition at line 550 of file chan_sip.c.
int expiry = DEFAULT_EXPIRY [static] |
Definition at line 186 of file chan_sip.c.
time_t externexpire = 0 [static] |
Expiration counter for re-resolving external host name in dynamic DNS
Definition at line 1186 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 1185 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 1184 of file chan_sip.c.
int externrefresh = 10 [static] |
Definition at line 1187 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 541 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 542 of file chan_sip.c.
enum transfermodes global_allowtransfer [static] |
SIP Refer restriction scheme
Definition at line 558 of file chan_sip.c.
int global_alwaysauthreject [static] |
Send 401 Unauthorized for all failing requests
Definition at line 531 of file chan_sip.c.
int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 557 of file chan_sip.c.
int global_callevents [static] |
Whether we send manager events or not
Definition at line 555 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 526 of file chan_sip.c.
struct ast_flags global_flags[2] = {{0}} [static] |
global SIP_ flags
Definition at line 573 of file chan_sip.c.
Referenced by build_peer(), build_radius_record(), build_user(), destroy_association(), get_destination(), load_module(), realtime_update_peer(), reload_config(), set_peer_defaults(), sip_alloc(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), sip_no_debug_deprecated(), sip_show_settings(), transmit_response_using_temp(), and update_peer().
struct ast_jb_conf global_jbconf [static] |
Definition at line 220 of file chan_sip.c.
int global_limitonpeers [static] |
Match call limit on peers only
Definition at line 527 of file chan_sip.c.
int global_matchexterniplocally [static] |
Match externip/externhost setting against localnet setting
Definition at line 560 of file chan_sip.c.
int global_mwitime [static] |
Time between MWI checks for peers
Definition at line 544 of file chan_sip.c.
int global_notifyhold [static] |
Send notifications on hold
Definition at line 530 of file chan_sip.c.
int global_notifyringing [static] |
Send notifications on ringing
Definition at line 529 of file chan_sip.c.
char global_realm[MAXHOSTNAMELEN] [static] |
Default realm
Definition at line 551 of file chan_sip.c.
int global_reg_timeout [static] |
Definition at line 539 of file chan_sip.c.
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 540 of file chan_sip.c.
char global_regcontext[AST_MAX_CONTEXT] [static] |
Context for auto-extensions
Definition at line 552 of file chan_sip.c.
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 535 of file chan_sip.c.
int global_rtautoclear [static] |
Definition at line 528 of file chan_sip.c.
int global_rtpholdtimeout [static] |
Definition at line 537 of file chan_sip.c.
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 538 of file chan_sip.c.
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 536 of file chan_sip.c.
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 556 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 546 of file chan_sip.c.
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 545 of file chan_sip.c.
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 547 of file chan_sip.c.
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 553 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 11333 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 594 of file chan_sip.c.
List of local networks, on the same side of NAT as this Asterisk
Definition at line 1188 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 9967 of file chan_sip.c.
char mandescr_show_peers[] [static] |
Initial value:
"Description: Lists SIP peers in text format with details on current status.\n" "Variables: \n" " ActionID: <id> Action ID for this transaction. Will be returned.\n"
Definition at line 9518 of file chan_sip.c.
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Maximum accepted registration time
Definition at line 184 of file chan_sip.c.
int min_expiry = DEFAULT_MIN_EXPIRY [static] |
Minimum accepted registration time
Definition at line 183 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 588 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 11325 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 11329 of file chan_sip.c.
const char notify_config[] = "sip_notify.conf" [static] |
Definition at line 223 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 1194 of file chan_sip.c.
Referenced by complete_sipnotify(), and sip_notify().
char notify_usage[] [static] |
Initial value:
"Usage: sip notify <type> <peer> [<peer>...]\n" " Send a NOTIFY message to a SIP peer or peers\n" " Message types are defined in sip_notify.conf\n"
Definition at line 11265 of file chan_sip.c.
int ourport [static] |
Definition at line 1191 of file chan_sip.c.
struct sockaddr_in outboundproxyip [static] |
int pedanticsipchecking [static] |
Extra checking ? Default off
Definition at line 533 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 11307 of file chan_sip.c.
int recordhistory [static] |
Record SIP history. Off by default
Definition at line 549 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 571 of file chan_sip.c.
int rpeerobjs = 0 [static] |
Realtime peers
Definition at line 569 of file chan_sip.c.
int ruserobjs = 0 [static] |
Realtime users
Definition at line 567 of file chan_sip.c.
struct sched_context* sched [static] |
The scheduling context
Definition at line 593 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 11289 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 11285 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 11260 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 11293 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 11280 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 11346 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 11302 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 11297 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 11312 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 11350 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 11342 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 11275 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 11270 of file chan_sip.c.
struct ast_custom_function sip_header_function [static] |
struct cfsip_methods sip_methods[] [static] |
XXX Note that sip_methods[i].id == i must hold or the code breaks
Referenced by __sip_ack(), __sip_autodestruct(), __sip_destroy(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), check_auth(), do_proxy_auth(), find_sip_method(), get_destination(), handle_request(), handle_request_subscribe(), handle_response(), init_req(), initreqprep(), method_match(), reqprep(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_scheddestroy(), and transmit_register().
struct cfsip_options sip_options[] [static] |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly.
Referenced by _sip_show_peer(), parse_sip_options(), and sip_show_channel().
char sip_reload_usage[] [static] |
Initial value:
"Usage: sip reload\n" " Reloads SIP configuration from sip.conf\n"
Definition at line 11338 of file chan_sip.c.
int sip_reloading = FALSE [static] |
Flag for avoiding multiple reloads at the same time
Definition at line 590 of file chan_sip.c.
enum channelreloadreason sip_reloadreason [static] |
Reason for last reload/load of configuration
Definition at line 591 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 1589 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 1532 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 1558 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 1598 of file chan_sip.c.
Referenced by load_module(), and unload_module().
struct ast_custom_function sipchaninfo_function [static] |
Structure to declare a dialplan function: SIPCHANINFO.
Definition at line 11587 of file chan_sip.c.
Referenced by load_module(), and unload_module().
Structure to declare a dialplan function: SIPPEER.
Definition at line 11507 of file chan_sip.c.
Referenced by load_module(), and unload_module().
int sipsock = -1 [static] |
Main socket for SIP network communication
Definition at line 1182 of file chan_sip.c.
Referenced by __sip_xmit(), do_monitor(), reg_source_db(), sipsock_read(), and unload_module().
int* sipsock_read_id [static] |
ID of IO entry for sipsock FD
Definition at line 595 of file chan_sip.c.
int speerobjs = 0 [static] |
Statis peers
Definition at line 568 of file chan_sip.c.
int srvlookup [static] |
SRV Lookup on or off. Default is off, RFC behavior is on
Definition at line 532 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 566 of file chan_sip.c.
char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static] |
Definition at line 17011 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 17016 of file chan_sip.c.
struct ast_user_list userl [static] |
The user list: Users and friends.