#include "asterisk.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <regex.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/compiler.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"
Go to the source code of this file.
Data Structures | |
struct | ast_peer_list |
The peer list: Peers and Friends. More... | |
struct | ast_register_list |
The register list: Other SIP proxys we register with and place calls to. More... | |
struct | ast_user_list |
The user list: Users and friends. More... | |
struct | c_referstatusstring |
struct | cfsip_methods |
struct | cfsip_options |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More... | |
struct | cfsubscription_types |
struct | domain |
Domain data structure. More... | |
struct | domain_list |
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_history_head |
struct | sip_invite_param |
Parameters to the transmit_invite function. More... | |
struct | sip_peer |
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host). More... | |
struct | sip_pkt |
sip packet - raw format for outbound packets that are sent or scheduled for transmission More... | |
struct | sip_pvt |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe More... | |
struct | sip_pvt::request_queue |
struct | sip_refer |
Structure to handle SIP transfers. Dynamically allocated when needed. More... | |
struct | sip_registry |
Registrations with other SIP proxies. More... | |
struct | sip_request |
sip_request: The data grabbed from the UDP socket More... | |
struct | sip_route |
Structure to save routing information for a SIP session. More... | |
struct | sip_user |
Structure for SIP user data. User's place calls to us. More... | |
struct | t38properties |
T.38 channel settings (at some point we need to make this alloc'ed. More... | |
Defines | |
#define | ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
SIP Methods we support. | |
#define | append_history(p, event, fmt, args...) append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history. | |
#define | CALLERID_UNKNOWN "Unknown" |
#define | CAN_CREATE_DIALOG 1 |
#define | CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
#define | CAN_NOT_CREATE_DIALOG 0 |
#define | CHECK_AUTH_BUF_INITLEN 256 |
#define | DEC_CALL_LIMIT 0 |
#define | DEC_CALL_RINGING 2 |
#define | DEFAULT_ALLOW_EXT_DOM TRUE |
#define | DEFAULT_ALLOWGUEST TRUE |
#define | DEFAULT_AUTOCREATEPEER FALSE |
#define | DEFAULT_CALLERID "asterisk" |
#define | DEFAULT_COMPACTHEADERS FALSE |
#define | DEFAULT_CONTEXT "default" |
#define | DEFAULT_DEFAULT_EXPIRY 120 |
#define | DEFAULT_EXPIRY 900 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_CALL_BITRATE (384) |
#define | DEFAULT_MAX_EXPIRY 3600 |
#define | DEFAULT_MAX_FORWARDS "70" |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_MIN_EXPIRY 60 |
#define | DEFAULT_MOHINTERPRET "default" |
#define | DEFAULT_MOHSUGGEST "" |
#define | DEFAULT_MWITIME 10 |
#define | DEFAULT_NOTIFYMIME "application/simple-message-summary" |
#define | DEFAULT_NOTIFYRINGING TRUE |
#define | DEFAULT_PEDANTIC FALSE |
#define | DEFAULT_QUALIFY FALSE |
#define | DEFAULT_REALM "asterisk" |
#define | DEFAULT_REGISTRATION_TIMEOUT 20 |
#define | DEFAULT_RETRANS 1000 |
#define | DEFAULT_SRVLOOKUP TRUE |
#define | DEFAULT_T1MIN 100 |
#define | DEFAULT_TOS_AUDIO 0 |
#define | DEFAULT_TOS_SIP 0 |
#define | DEFAULT_TOS_VIDEO 0 |
#define | DEFAULT_TRANS_TIMEOUT -1 |
#define | DEFAULT_USERAGENT "Asterisk PBX" |
#define | DEFAULT_VMEXTEN "asterisk" |
#define | EXPIRY_GUARD_LIMIT 30 |
#define | EXPIRY_GUARD_MIN 500 |
#define | EXPIRY_GUARD_PCT 0.20 |
#define | EXPIRY_GUARD_SECS 15 |
#define | FALSE 0 |
#define | FLAG_FATAL (1 << 1) |
#define | FLAG_RESPONSE (1 << 0) |
#define | FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" |
#define | FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" |
#define | FORMAT "%-40.40s %-20.20s %-16.16s\n" |
#define | FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" |
#define | FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT3H "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" |
#define | FORMAT3L "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" |
#define | INC_CALL_LIMIT 1 |
#define | INC_CALL_RINGING 3 |
#define | INITIAL_CSEQ 101 |
#define | IPTOS_MINCOST 0x02 |
#define | MAX(a, b) ((a) > (b) ? (a) : (b)) |
#define | MAX_AUTHTRIES 3 |
#define | MAX_HISTORY_ENTRIES 50 |
#define | MAX_RETRANS 6 |
#define | NO_RTP 0 |
#define | NOT_SUPPORTED 0 |
#define | RTP 1 |
#define | SDP_MAX_RTPMAP_CODECS 32 |
#define | SDP_SAMPLE_RATE(x) 8000 |
#define | SIP_ALREADYGONE (1 << 0) |
#define | SIP_CALL_LIMIT (1 << 28) |
#define | SIP_CAN_REINVITE (1 << 20) |
#define | SIP_CAN_REINVITE_NAT (2 << 20) |
#define | SIP_DEFER_BYE_ON_TRANSFER (1 << 15) |
#define | SIP_DTMF (3 << 16) |
#define | SIP_DTMF_AUTO (3 << 16) |
#define | SIP_DTMF_INBAND (1 << 16) |
#define | SIP_DTMF_INFO (2 << 16) |
#define | SIP_DTMF_RFC2833 (0 << 16) |
#define | SIP_FLAGS_TO_COPY |
#define | SIP_FREE_BIT (1 << 14) |
#define | SIP_G726_NONSTANDARD (1 << 31) |
#define | SIP_GOTREFER (1 << 7) |
#define | SIP_INC_COUNT (1 << 30) |
#define | SIP_INSECURE_INVITE (1 << 24) |
#define | SIP_INSECURE_PORT (1 << 23) |
#define | SIP_MAX_HEADERS 64 |
#define | SIP_MAX_LINES 64 |
#define | SIP_MAX_PACKET 4096 |
#define | SIP_NAT (3 << 18) |
#define | SIP_NAT_ALWAYS (3 << 18) |
#define | SIP_NAT_NEVER (0 << 18) |
#define | SIP_NAT_RFC3581 (1 << 18) |
#define | SIP_NAT_ROUTE (2 << 18) |
#define | SIP_NEEDDESTROY (1 << 1) |
#define | SIP_NEEDREINVITE (1 << 5) |
#define | SIP_NO_HISTORY (1 << 27) |
#define | SIP_NOVIDEO (1 << 2) |
#define | SIP_OPT_100REL (1 << 1) |
#define | SIP_OPT_EARLY_SESSION (1 << 3) |
#define | SIP_OPT_EVENTLIST (1 << 11) |
#define | SIP_OPT_GRUU (1 << 12) |
#define | SIP_OPT_HISTINFO (1 << 15) |
#define | SIP_OPT_JOIN (1 << 4) |
#define | SIP_OPT_NOREFERSUB (1 << 14) |
#define | SIP_OPT_PATH (1 << 5) |
#define | SIP_OPT_PRECONDITION (1 << 7) |
#define | SIP_OPT_PREF (1 << 6) |
#define | SIP_OPT_PRIVACY (1 << 8) |
#define | SIP_OPT_REPLACES (1 << 0) |
#define | SIP_OPT_RESPRIORITY (1 << 16) |
#define | SIP_OPT_SDP_ANAT (1 << 9) |
#define | SIP_OPT_SEC_AGREE (1 << 10) |
#define | SIP_OPT_TARGET_DIALOG (1 << 13) |
#define | SIP_OPT_TIMER (1 << 2) |
#define | SIP_OUTGOING (1 << 13) |
#define | SIP_PAGE2_ALLOWOVERLAP (1 << 17) |
#define | SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
#define | SIP_PAGE2_BUGGY_MWI (1 << 26) |
#define | SIP_PAGE2_CALL_ONHOLD (3 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_ACTIVE (1 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_INACTIVE (3 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_ONEDIR (2 << 23) |
#define | SIP_PAGE2_DEBUG (3 << 11) |
#define | SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
#define | SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
#define | SIP_PAGE2_DIALOG_ESTABLISHED (1 << 29) |
#define | SIP_PAGE2_DYNAMIC (1 << 13) |
#define | SIP_PAGE2_FLAGS_TO_COPY |
#define | SIP_PAGE2_IGNOREREGEXPIRE (1 << 10) |
#define | SIP_PAGE2_INC_RINGING (1 << 19) |
#define | SIP_PAGE2_OUTGOING_CALL (1 << 27) |
#define | SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) |
#define | SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
#define | SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
#define | SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
#define | SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
#define | SIP_PAGE2_RTUPDATE (1 << 1) |
#define | SIP_PAGE2_SELFDESTRUCT (1 << 14) |
#define | SIP_PAGE2_STATECHANGEQUEUE (1 << 9) |
#define | SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
#define | SIP_PAGE2_T38SUPPORT (7 << 20) |
#define | SIP_PAGE2_T38SUPPORT_RTP (2 << 20) |
#define | SIP_PAGE2_T38SUPPORT_TCP (4 << 20) |
#define | SIP_PAGE2_T38SUPPORT_UDPTL (1 << 20) |
#define | SIP_PAGE2_TCP (1 << 30) |
#define | SIP_PAGE2_TCP_CONNECTED (1 << 31) |
#define | SIP_PAGE2_UDPTL_DESTINATION (1 << 28) |
#define | SIP_PAGE2_VIDEOSUPPORT (1 << 15) |
#define | SIP_PENDINGBYE (1 << 6) |
#define | SIP_PKT_DEBUG (1 << 0) |
#define | SIP_PKT_IGNORE (1 << 2) |
#define | SIP_PKT_IGNORE_REQ (1 << 4) |
#define | SIP_PKT_IGNORE_RESP (1 << 3) |
#define | SIP_PKT_WITH_TOTAG (1 << 1) |
#define | SIP_PROG_INBAND (3 << 25) |
#define | SIP_PROG_INBAND_NEVER (0 << 25) |
#define | SIP_PROG_INBAND_NO (1 << 25) |
#define | SIP_PROG_INBAND_YES (2 << 25) |
#define | SIP_PROGRESS_SENT (1 << 4) |
#define | SIP_PROMISCREDIR (1 << 8) |
#define | SIP_REALTIME (1 << 11) |
#define | SIP_REINVITE (7 << 20) |
#define | SIP_REINVITE_UPDATE (4 << 20) |
#define | SIP_RINGING (1 << 3) |
#define | SIP_SENDRPID (1 << 29) |
#define | SIP_TRANS_TIMEOUT 32000 |
#define | SIP_TRUSTRPID (1 << 9) |
#define | SIP_USECLIENTCODE (1 << 12) |
#define | SIP_USEREQPHONE (1 << 10) |
#define | SIPBUFSIZE 512 |
#define | sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG) |
#define | sipdebug_config ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG) |
#define | sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
#define | STANDARD_SIP_PORT 5060 |
Standard SIP port from RFC 3261. DO NOT CHANGE THIS. | |
#define | SUPPORTED 1 |
#define | SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support. | |
#define | T38FAX_FILL_BIT_REMOVAL (1 << 0) |
#define | T38FAX_RATE_12000 (1 << 12) |
#define | T38FAX_RATE_14400 (1 << 13) |
#define | T38FAX_RATE_2400 (1 << 8) |
#define | T38FAX_RATE_4800 (1 << 9) |
#define | T38FAX_RATE_7200 (1 << 10) |
#define | T38FAX_RATE_9600 (1 << 11) |
#define | T38FAX_RATE_MANAGEMENT_LOCAL_TCF (1 << 3) |
#define | T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
#define | T38FAX_TRANSCODING_JBIG (1 << 2) |
#define | T38FAX_TRANSCODING_MMR (1 << 1) |
#define | T38FAX_UDP_EC_FEC (1 << 4) |
#define | T38FAX_UDP_EC_NONE (0 << 4) |
#define | T38FAX_UDP_EC_REDUNDANCY (2 << 4) |
#define | T38FAX_VERSION (3 << 6) |
#define | T38FAX_VERSION_0 (0 << 6) |
#define | T38FAX_VERSION_1 (1 << 6) |
#define | TRUE 1 |
#define | UNLINK(element, head, prev) |
#define | VIDEO_CODEC_MASK 0x1fc0000 |
#define | XMIT_ERROR -2 |
Enumerations | |
enum | check_auth_result { AUTH_SUCCESSFUL = 0, AUTH_CHALLENGE_SENT = 1, AUTH_SECRET_FAILED = -1, AUTH_USERNAME_MISMATCH = -2, AUTH_NOT_FOUND = -3, AUTH_FAKE_AUTH = -4, AUTH_UNKNOWN_DOMAIN = -5, AUTH_PEER_NOT_DYNAMIC = -6, AUTH_ACL_FAILED = -7 } |
Authentication result from check_auth* functions. More... | |
enum | domain_mode { SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG } |
Modes for SIP domain handling in the PBX. More... | |
enum | invitestates { INV_NONE = 0, INV_CALLING = 1, INV_PROCEEDING = 2, INV_EARLY_MEDIA = 3, INV_COMPLETED = 4, INV_CONFIRMED = 5, INV_TERMINATED = 6, INV_CANCELLED = 7 } |
States for the INVITE transaction, not the dialog. More... | |
enum | parse_register_result { PARSE_REGISTER_FAILED, PARSE_REGISTER_UPDATE, PARSE_REGISTER_QUERY } |
enum | referstatus { REFER_IDLE, REFER_SENT, REFER_RECEIVED, REFER_CONFIRMED, REFER_ACCEPTED, REFER_RINGING, REFER_200OK, REFER_FAILED, REFER_NOAUTH } |
Parameters to know status of transfer. More... | |
enum | sip_auth_type { PROXY_AUTH, WWW_AUTH } |
Authentication types - proxy or www authentication. More... | |
enum | sip_result { AST_SUCCESS = 0, AST_FAILURE = -1 } |
enum | sipmethod { SIP_UNKNOWN, SIP_RESPONSE, SIP_REGISTER, SIP_OPTIONS, SIP_NOTIFY, SIP_INVITE, SIP_ACK, SIP_PRACK, SIP_BYE, SIP_REFER, SIP_SUBSCRIBE, SIP_MESSAGE, SIP_UPDATE, SIP_INFO, SIP_CANCEL, SIP_PUBLISH, SIP_PING } |
SIP Request methods known by Asterisk. More... | |
enum | sipregistrystate { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH, REG_STATE_FAILED } |
States for outbound registrations (with register= lines in sip.conf. More... | |
enum | subscriptiontype { NONE = 0, XPIDF_XML, DIALOG_INFO_XML, CPIM_PIDF_XML, PIDF_XML, MWI_NOTIFICATION } |
enum | t38state { T38_DISABLED = 0, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, T38_PEER_DIRECT, T38_PEER_REINVITE, T38_ENABLED } |
T38 States for a call. More... | |
enum | transfermodes { TRANSFER_OPENFORALL, TRANSFER_CLOSED } |
Authorization scheme for call transfers. More... | |
enum | xmittype { XMIT_CRITICAL = 2, XMIT_RELIABLE = 1, XMIT_UNRELIABLE = 0 } |
Functions | |
static const char * | __get_header (const struct sip_request *req, const char *name, int *start) |
static void | __reg_module (void) |
static int | __set_address_from_contact (const char *fullcontact, struct sockaddr_in *sin) |
static void | __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
Acknowledges receipt of a packet and stops retransmission called with p locked. | |
static int | __sip_autodestruct (const void *data) |
Kill a SIP dialog (called by scheduler). | |
static int | __sip_destroy (struct sip_pvt *p, int lockowner) |
Execute destruction of SIP dialog structure, release memory. | |
static int | __sip_do_register (struct sip_registry *r) |
Register with SIP proxy. | |
static void | __sip_pretend_ack (struct sip_pvt *p) |
Pretend to ack all packets called with p locked. | |
static int | __sip_reliable_xmit (struct sip_pvt *p, int seqno, int resp, char *data, int len, int fatal, int sipmethod) |
Transmit packet with retransmits. | |
static int | __sip_semi_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
Acks receipt of packet, keep it around (used for provisional responses). | |
static int | __sip_show_channels (int fd, int argc, char *argv[], int subscriptions) |
SIP show channels CLI (main function). | |
static int | __sip_xmit (struct sip_pvt *p, char *data, int len) |
Transmit SIP message. | |
static int | __transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Base transmit response function. | |
static void | __unreg_module (void) |
static int | _sip_show_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
Show one peer in detail (main function). | |
static int | _sip_show_peers (int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
_sip_show_peers: Execute sip show peers command | |
static int | acf_channel_read (struct ast_channel *chan, char *funcname, char *preparse, char *buf, size_t buflen) |
static void | add_blank (struct sip_request *req) |
add a blank line if no body | |
static void | add_codec_to_sdp (const struct sip_pvt *p, int codec, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug, int *min_packet_size) |
Add codec offer to SDP offer/answer body in INVITE or 200 OK. | |
static int | add_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 | append_history_va (struct sip_pvt *p, const char *fmt, va_list ap) |
Append to SIP dialog history with arg list. | |
static void | ast_quiet_chan (struct ast_channel *chan) |
Turn off generator data XXX Does this function belong in the SIP channel? | |
static int | ast_sip_ouraddrfor (struct in_addr *them, struct in_addr *us) |
NAT fix - decide which IP address to use for ASterisk server? | |
static int | attempt_transfer (struct sip_dual *transferer, struct sip_dual *target) |
Attempt transfer of SIP call This fix for attended transfers on a local PBX. | |
static int | auto_congest (const void *nothing) |
Scheduled congestion on a call. | |
static void | build_callid_pvt (struct sip_pvt *pvt) |
Build SIP Call-ID value for a non-REGISTER transaction. | |
static void | build_callid_registry (struct sip_registry *reg, struct in_addr ourip, const char *fromdomain) |
Build SIP Call-ID value for a REGISTER transaction. | |
static void | build_contact (struct sip_pvt *p) |
Build contact header - the contact header we send out. | |
static struct sip_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
Build peer from configuration (file or realtime static/dynamic). | |
static int | build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len) |
Build reply digest. | |
static void | build_route (struct sip_pvt *p, struct sip_request *req, int backwards) |
Build route list from Record-Route header. | |
static void | build_rpid (struct sip_pvt *p) |
Build the Remote Party-ID & From using callingpres options. | |
static struct sip_user * | build_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
Initiate a SIP user structure from configuration (configuration or realtime). | |
static void | build_via (struct sip_pvt *p) |
Build a Via header for a request. | |
static int | cb_extensionstate (char *context, char *exten, int state, void *data) |
Callback for the devicestate notification (SUBSCRIBE) support subsystem. | |
static void | change_hold_state (struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly) |
Change hold state for a call. | |
static enum check_auth_result | check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, char *uri, enum xmittype reliable, int ignore) |
Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set). | |
static void | check_auth_buf_init (void) |
static void | check_pendings (struct sip_pvt *p) |
Check pending actions on SIP call. | |
static int | check_sip_domain (const char *domain, char *context, size_t len) |
check_sip_domain: Check if domain part of uri is local to our server | |
static int | check_user (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin) |
Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced. | |
static enum check_auth_result | check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin, struct sip_peer **authpeer) |
Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests. | |
static void | check_via (struct sip_pvt *p, const struct sip_request *req) |
check Via: header for hostname, port and rport request/answer | |
static void | cleanup_stale_contexts (char *new, char *old) |
Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly. | |
static int | clear_realm_authentication (struct sip_auth *authlist) |
Clear realm authentication list (at reload). | |
static void | clear_sip_domains (void) |
Clear our domain list (at reload). | |
static char * | complete_sip_debug_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip debug peer' CLI. | |
static char * | complete_sip_peer (const char *word, int state, int flags2) |
Do completion on peer name. | |
static char * | complete_sip_prune_realtime_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip prune realtime peer' CLI. | |
static char * | complete_sip_prune_realtime_user (const char *line, const char *word, int pos, int state) |
Support routine for 'sip prune realtime user' CLI. | |
static char * | complete_sip_show_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show peer' CLI. | |
static char * | complete_sip_show_user (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show user' CLI. | |
static char * | complete_sip_user (const char *word, int state, int flags2) |
Do completion on user name. | |
static char * | complete_sipch (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show channel' CLI. | |
static char * | complete_sipnotify (const char *line, const char *word, int pos, int state) |
Support routine for 'sip notify' CLI. | |
static int | copy_all_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy all headers from one request to another. | |
static int | copy_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy one header field from one request to another. | |
static void | copy_request (struct sip_request *dst, const struct sip_request *src) |
copy SIP request (mostly used to save request for responses) | |
static int | copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy SIP VIA Headers from the request to the response. | |
static int | create_addr (struct sip_pvt *dialog, const char *opeer) |
create address structure from peer name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success | |
static int | create_addr_from_peer (struct sip_pvt *dialog, struct sip_peer *peer) |
Create address structure from peer reference. return -1 on error, 0 on success. | |
static void | destroy_association (struct sip_peer *peer) |
Remove registration data from realtime database or AST/DB when registration expires. | |
static int | determine_firstline_parts (struct sip_request *req) |
Parse first line of incoming SIP request. | |
static void * | do_monitor (void *data) |
The SIP monitoring thread. | |
static int | do_proxy_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader, int sipmethod, int init) |
Add authentication on outbound SIP packet. | |
static int | do_register_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader) |
Authenticate for outbound registration. | |
static void | do_setnat (struct sip_pvt *p, int natflags) |
Set nat mode on the various data sockets. | |
static int | does_peer_need_mwi (struct sip_peer *peer) |
Check whether peer needs a new MWI notification check. | |
static const char * | domain_mode_to_text (const enum domain_mode mode) |
Print domain mode to cli. | |
static const char * | dtmfmode2str (int mode) |
Convert DTMF mode to printable string. | |
static int | expire_register (const void *data) |
Expire registration of SIP peer. | |
static void | extract_uri (struct sip_pvt *p, struct sip_request *req) |
Check Contact: URI of SIP message. | |
static const char * | find_alias (const char *name, const char *_default) |
Find compressed SIP alias. | |
static struct sip_pvt * | find_call (struct sip_request *req, struct sockaddr_in *sin, const int intended_method) |
Connect incoming SIP message to current dialog or create new dialog structure Called by handle_request, sipsock_read. | |
static const char * | find_closing_quote (const char *start, const char *lim) |
Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote. | |
static struct sip_peer * | find_peer (const char *peer, struct sockaddr_in *sin, int realtime, int devstate_only) |
Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name. | |
static struct sip_auth * | find_realm_authentication (struct sip_auth *authlist, const char *realm) |
Find authentication for a specific realm. | |
static int | find_sdp (struct sip_request *req) |
Determine whether a SIP message contains an SDP in its body. | |
static int | find_sip_method (const char *msg) |
find_sip_method: Find SIP method from header | |
static struct cfsubscription_types * | find_subscription_type (enum subscriptiontype subtype) |
Find subscription type in array. | |
static struct sip_user * | find_user (const char *name, int realtime) |
Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf). | |
static void | free_old_route (struct sip_route *route) |
Remove route from route list. | |
static int | func_check_sipdomain (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
Dial plan function to check if domain is local. | |
static int | func_header_read (struct ast_channel *chan, char *function, char *data, char *buf, size_t len) |
Read SIP header (dialplan function). | |
static int | function_sipchaninfo_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
${SIPCHANINFO()} Dialplan function - reads sip channel data | |
static int | function_sippeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
${SIPPEER()} Dialplan function - reads peer data | |
static char * | generate_random_string (char *buf, size_t size) |
Generate 32 byte random string for callid's etc. | |
static int | get_also_info (struct sip_pvt *p, struct sip_request *oreq) |
Call transfer support (old way, deprecated by the IETF)--. | |
static char * | get_body (struct sip_request *req, char *name) |
Get a specific line from the message body. | |
static char * | get_body_by_line (const char *line, const char *name, int nameLen) |
Reads one line of SIP message body. | |
static char * | get_calleridname (const char *input, char *output, size_t outputsize) |
Get caller id name from SIP headers. | |
static int | get_destination (struct sip_pvt *p, struct sip_request *oreq) |
Find out who the call is for We use the INVITE uri to find out. | |
static const char * | get_header (const struct sip_request *req, const char *name) |
Get header from SIP request. | |
static char * | get_in_brackets (char *tmp) |
Pick out text in brackets from character string. | |
static int | get_msg_text (char *buf, int len, struct sip_request *req) |
Get text out of a SIP MESSAGE packet. | |
static int | get_rdnis (struct sip_pvt *p, struct sip_request *oreq) |
Get referring dnis. | |
static int | get_refer_info (struct sip_pvt *transferer, struct sip_request *outgoing_req) |
Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure. | |
static int | get_rpid_num (const char *input, char *output, int maxlen) |
Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found. | |
static const char * | get_sdp (struct sip_request *req, const char *name) |
Get a line from an SDP message body. | |
static const char * | get_sdp_iterate (int *start, struct sip_request *req, const char *name) |
Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number. | |
static struct sip_pvt * | get_sip_pvt_byid_locked (const char *callid, const char *totag, const char *fromtag) |
Lock interface lock and find matching pvt lock. | |
static const char * | gettag (const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize) |
Get tag from packet. | |
static int | handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v) |
Handle flag-type options common to configuration of devices - users and peers. | |
static int | handle_invite_replaces (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin) |
Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. | |
static int | handle_request (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock) |
Handle incoming SIP requests (methods). | |
static int | handle_request_bye (struct sip_pvt *p, struct sip_request *req) |
Handle incoming BYE request. | |
static int | handle_request_cancel (struct sip_pvt *p, struct sip_request *req) |
Handle incoming CANCEL request. | |
static void | handle_request_info (struct sip_pvt *p, struct sip_request *req) |
Receive SIP INFO Message. | |
static int | handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, char *e, int *nounlock) |
Handle incoming INVITE request. | |
static int | handle_request_message (struct sip_pvt *p, struct sip_request *req) |
Handle incoming MESSAGE request. | |
static int | handle_request_notify (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e) |
Handle incoming notifications. | |
static int | handle_request_options (struct sip_pvt *p, struct sip_request *req) |
Handle incoming OPTIONS request. | |
static int | handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, int *nounlock) |
static int | handle_request_register (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, char *e) |
Handle incoming REGISTER request. | |
static int | handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e) |
Handle incoming SUBSCRIBE request. | |
static void | handle_response (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
Handle SIP response in dialogue. | |
static void | handle_response_invite (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno) |
Handle SIP response to INVITE dialogue. | |
static void | handle_response_peerpoke (struct sip_pvt *p, int resp, struct sip_request *req) |
Handle qualification responses (OPTIONS). | |
static void | handle_response_refer (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno) |
static int | handle_response_register (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
Handle responses on REGISTER to services. | |
static const char * | hangup_cause2sip (int cause) |
Convert Asterisk hangup causes to SIP codes. | |
static int | hangup_sip2cause (int cause) |
Convert SIP hangup causes to Asterisk hangup causes. | |
static int | init_req (struct sip_request *req, int sipmethod, const char *recip) |
Initialize SIP request. | |
static int | init_resp (struct sip_request *resp, const char *msg) |
Initialize SIP response, based on SIP request. | |
static void | initialize_initreq (struct sip_pvt *p, struct sip_request *req) |
Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog. | |
static void | initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod) |
Initiate new SIP request to peer/user. | |
static const char * | insecure2str (int port, int invite) |
Convert Insecure setting to printable string. | |
static void | list_route (struct sip_route *route) |
List all routes - mostly for debugging. | |
static int | load_module (void) |
PBX load module - initialization. | |
static int | local_attended_transfer (struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno) |
Find all call legs and bridge transferee with target called from handle_request_refer. | |
static int | lws2sws (char *msgbuf, int len) |
Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled. | |
static void | make_our_tag (char *tagbuf, size_t len) |
Make our SIP dialog tag. | |
static int | manager_sip_show_peer (struct mansession *s, const struct message *m) |
Show SIP peers in the manager API. | |
static int | manager_sip_show_peers (struct mansession *s, const struct message *m) |
Show SIP peers in the manager API. | |
static int | method_match (enum sipmethod id, const char *name) |
returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send | |
static char * | nat2str (int nat) |
Convert NAT setting to text string. | |
static void | parse_copy (struct sip_request *dst, const struct sip_request *src) |
Copy SIP request, parse it. | |
static void | parse_moved_contact (struct sip_pvt *p, struct sip_request *req) |
Parse 302 Moved temporalily response. | |
static int | parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req) |
Save contact header for 200 OK on INVITE. | |
static enum parse_register_result | parse_register_contact (struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req) |
Parse contact header and save registration (peer registration). | |
static int | parse_request (struct sip_request *req) |
Parse a SIP message. | |
static unsigned int | parse_sip_options (struct sip_pvt *pvt, const char *supported) |
Parse supported header in incoming packet. | |
static int | peer_status (struct sip_peer *peer, char *status, int statuslen) |
Report Peer status in character string. | |
static void | print_codec_to_cli (int fd, struct ast_codec_pref *pref) |
Print codec list from preference to CLI/manager. | |
static void | print_group (int fd, ast_group_t group, int crlf) |
Print call group and pickup group. | |
static void | process_request_queue (struct sip_pvt *p, int *recount, int *nounlock) |
static int | process_sdp (struct sip_pvt *p, struct sip_request *req) |
Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp(). | |
static int | queue_request (struct sip_pvt *p, const struct sip_request *req) |
static struct sip_peer * | realtime_peer (const char *newpeername, struct sockaddr_in *sin, int devstate_only) |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf | |
static void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey) |
Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups. | |
static struct sip_user * | realtime_user (const char *username) |
Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped). | |
static void | receive_message (struct sip_pvt *p, struct sip_request *req) |
Receive SIP MESSAGE method messages. | |
static char * | referstatus2str (enum referstatus rstatus) |
Convert transfer status to string. | |
static void | reg_source_db (struct sip_peer *peer) |
Get registration details from Asterisk DB. | |
static void | register_peer_exten (struct sip_peer *peer, int onoff) |
Automatically add peer extension to dial plan. | |
static enum check_auth_result | register_verify (struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri) |
Verify registration of user
| |
static char * | regstate2str (enum sipregistrystate regstate) |
Convert registration state status to string. | |
static int | reload (void) |
Part of Asterisk module interface. | |
static int | reload_config (enum channelreloadreason reason) |
Re-read SIP.conf config file. | |
static int | reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len) |
reply to authentication for outbound registrations | |
static int | reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch) |
Initialize a SIP request message (not the initial one in a dialog). | |
static int | respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Prepare SIP response packet. | |
static int | restart_monitor (void) |
Start the channel monitor thread. | |
static int | retrans_pkt (const void *data) |
Retransmit SIP message if no answer (Called from scheduler). | |
static int | scheduler_process_request_queue (const void *data) |
static int | send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
Send SIP Request to the other part of the dialogue. | |
static int | send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
Transmit response on SIP request. | |
static int | set_address_from_contact (struct sip_pvt *pvt) |
Change the other partys IP address based on given contact. | |
static void | set_destination (struct sip_pvt *p, char *uri) |
Set destination from SIP URI. | |
static void | set_insecure_flags (struct ast_flags *flags, const char *value, int lineno) |
Parse the "insecure" setting from sip.conf or from realtime. | |
static void | set_peer_defaults (struct sip_peer *peer) |
Set peer defaults before configuring specific configurations. | |
static int | sip_addheader (struct ast_channel *chan, void *data) |
Add a SIP header to an outbound INVITE. | |
static int | sip_addrcmp (char *name, struct sockaddr_in *sin) |
Support routine for find_peer. | |
static struct sip_pvt * | sip_alloc (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method) |
Allocate SIP_PVT structure and set defaults. | |
static void | sip_alreadygone (struct sip_pvt *dialog) |
static int | sip_answer (struct ast_channel *ast) |
sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface | |
static int | sip_call (struct ast_channel *ast, char *dest, int timeout) |
Initiate SIP call from PBX used from the dial() application. | |
static int | sip_cancel_destroy (struct sip_pvt *p) |
Cancel destruction of SIP dialog. | |
static int | sip_debug_test_addr (const struct sockaddr_in *addr) |
See if we pass debug IP filter. | |
static int | sip_debug_test_pvt (struct sip_pvt *p) |
Test PVT for debugging output. | |
static void | sip_destroy (struct sip_pvt *p) |
Destroy SIP call structure. | |
static void | sip_destroy_peer (struct sip_peer *peer) |
Destroy peer object from memory. | |
static void | sip_destroy_user (struct sip_user *user) |
Remove user object from in-memory storage. | |
static int | sip_devicestate (void *data) |
Part of PBX channel interface. | |
static int | sip_do_debug (int fd, int argc, char *argv[]) |
Turn on SIP debugging (CLI command). | |
static int | sip_do_debug_deprecated (int fd, int argc, char *argv[]) |
static int | sip_do_debug_ip (int fd, int argc, char *argv[]) |
Enable SIP Debugging in CLI. | |
static int | sip_do_debug_peer (int fd, int argc, char *argv[]) |
sip_do_debug_peer: Turn on SIP debugging with peer mask | |
static int | sip_do_history (int fd, int argc, char *argv[]) |
Enable SIP History logging (CLI). | |
static int | sip_do_reload (enum channelreloadreason reason) |
Reload module. | |
static int | sip_dtmfmode (struct ast_channel *chan, void *data) |
Set the DTMFmode for an outbound SIP call (application). | |
static void | sip_dump_history (struct sip_pvt *dialog) |
Dump SIP history to debug log file at end of lifespan for SIP dialog. | |
static int | sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links | |
static int | sip_get_codec (struct ast_channel *chan) |
Return SIP UA's codec (part of the RTP interface). | |
static enum ast_rtp_get_result | sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
Returns null if we can't reinvite audio (part of RTP interface). | |
static struct ast_udptl * | sip_get_udptl_peer (struct ast_channel *chan) |
static enum ast_rtp_get_result | sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
Returns null if we can't reinvite video (part of RTP interface). | |
static int | sip_handle_t38_reinvite (struct ast_channel *chan, struct sip_pvt *pvt, int reinvite) |
Handle T38 reinvite. | |
static int | sip_hangup (struct ast_channel *ast) |
sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup | |
static int | sip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen) |
Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc. | |
static const char * | sip_nat_mode (const struct sip_pvt *p) |
Display SIP nat mode. | |
static struct ast_channel * | sip_new (struct sip_pvt *i, int state, const char *title) |
Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels. | |
static int | sip_no_debug (int fd, int argc, char *argv[]) |
Disable SIP Debugging in CLI. | |
static int | sip_no_debug_deprecated (int fd, int argc, char *argv[]) |
static int | sip_no_history (int fd, int argc, char *argv[]) |
Disable SIP History logging (CLI). | |
static int | sip_notify (int fd, int argc, char *argv[]) |
Cli command to send SIP notify to peer. | |
static int | sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno) |
Park a call using the subsystem in res_features.c This is executed in a separate thread. | |
static void * | sip_park_thread (void *stuff) |
Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup. | |
static void | sip_peer_hold (struct sip_pvt *p, int hold) |
Change onhold state of a peer using a pvt structure. | |
static void | sip_poke_all_peers (void) |
Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions? | |
static int | sip_poke_noanswer (const void *data) |
React to lack of answer to Qualify poke. | |
static int | sip_poke_peer (struct sip_peer *peer) |
Check availability of peer, also keep NAT open. | |
static int | sip_poke_peer_s (const void *data) |
Poke peer (send qualify to check if peer is alive and well). | |
static int | sip_prune_realtime (int fd, int argc, char *argv[]) |
Remove temporary realtime objects from memory (CLI). | |
static struct ast_frame * | sip_read (struct ast_channel *ast) |
Read SIP RTP from channel. | |
static struct sockaddr_in * | sip_real_dst (const struct sip_pvt *p) |
The real destination address for a write. | |
static int | sip_refer_allocate (struct sip_pvt *p) |
Allocate SIP refer structure. | |
static int | sip_reg_timeout (const void *data) |
Registration timeout, register again. | |
static int | sip_register (char *value, int lineno) |
Parse register=> line in sip.conf and add to registry. | |
static void | sip_registry_destroy (struct sip_registry *reg) |
Destroy registry object Objects created with the register= statement in static configuration. | |
static int | sip_reinvite_retry (const void *data) |
Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler. | |
static int | sip_reload (int fd, int argc, char *argv[]) |
Force reload of module from cli. | |
static struct ast_channel * | sip_request_call (const char *type, int format, void *data, int *cause) |
PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here. | |
static int | sip_reregister (const void *data) |
Update registration with SIP Proxy. | |
static struct ast_frame * | sip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect) |
Read RTP from network. | |
static void | sip_scheddestroy (struct sip_pvt *p, int ms) |
Schedule destruction of SIP dialog. | |
static void | sip_send_all_registers (void) |
Send all known registrations. | |
static int | sip_send_mwi_to_peer (struct sip_peer *peer) |
Send message waiting indication to alert peer that they've got voicemail. | |
static int | sip_senddigit_begin (struct ast_channel *ast, char digit) |
static int | sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration) |
Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously. | |
static int | sip_sendtext (struct ast_channel *ast, const char *text) |
Send SIP MESSAGE text within a call Called from PBX core sendtext() application. | |
static int | sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active) |
Set the RTP peer for this call. | |
static int | sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl) |
static int | sip_show_channel (int fd, int argc, char *argv[]) |
Show details of one active dialog. | |
static int | sip_show_channels (int fd, int argc, char *argv[]) |
Show active SIP channels. | |
static int | sip_show_domains (int fd, int argc, char *argv[]) |
CLI command to list local domains. | |
static int | sip_show_history (int fd, int argc, char *argv[]) |
Show history details of one dialog. | |
static int | sip_show_inuse (int fd, int argc, char *argv[]) |
CLI Command to show calls within limits set by call_limit. | |
static int | sip_show_objects (int fd, int argc, char *argv[]) |
List all allocated SIP Objects (realtime or static). | |
static int | sip_show_peer (int fd, int argc, char *argv[]) |
Show one peer in detail. | |
static int | sip_show_peers (int fd, int argc, char *argv[]) |
CLI Show Peers command. | |
static int | sip_show_registry (int fd, int argc, char *argv[]) |
Show SIP Registry (registrations with other SIP proxies. | |
static int | sip_show_settings (int fd, int argc, char *argv[]) |
List global settings for the SIP channel. | |
static int | sip_show_subscriptions (int fd, int argc, char *argv[]) |
Show active SIP subscriptions. | |
static int | sip_show_user (int fd, int argc, char *argv[]) |
Show one user in detail. | |
static int | sip_show_users (int fd, int argc, char *argv[]) |
CLI Command 'SIP Show Users'. | |
static int | sip_sipredirect (struct sip_pvt *p, const char *dest) |
Transfer call before connect with a 302 redirect. | |
static int | sip_transfer (struct ast_channel *ast, const char *dest) |
Transfer SIP call. | |
static int | sip_uri_cmp (const char *input1, const char *input2) |
static int | sip_uri_headers_cmp (const char *input1, const char *input2) |
helper routine for sip_uri_cmp | |
static int | sip_uri_params_cmp (const char *input1, const char *input2) |
helper routine for sip_uri_cmp | |
static int | sip_write (struct ast_channel *ast, struct ast_frame *frame) |
Send frame to media channel (rtp). | |
static int | sipsock_read (int *id, int fd, short events, void *ignore) |
Read data from SIP socket. | |
static int | siptcpsock_accept (int *id, int fd, short events, void *ignore) |
Accept incoming TCP connections. | |
static void | stop_media_flows (struct sip_pvt *p) |
Immediately stop RTP, VRTP and UDPTL as applicable. | |
static const char * | subscription_type2str (enum subscriptiontype subtype) |
Show subscription type in string format. | |
static int | t38_get_rate (int t38cap) |
Get Max T.38 Transmission rate from T38 capabilities. | |
static struct sip_peer * | temp_peer (const char *name) |
Create temporary peer (used in autocreatepeer mode). | |
static void | temp_pvt_cleanup (void *) |
static void | temp_pvt_init (void) |
A per-thread temporary pvt structure. | |
static char * | transfermode2str (enum transfermodes mode) |
Convert transfer mode to text string. | |
static void | transmit_fake_auth_response (struct sip_pvt *p, struct sip_request *req, int reliable) |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers. | |
static int | transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration) |
Send SIP INFO dtmf message, see Cisco documentation on cisco.com. | |
static int | transmit_info_with_vidupdate (struct sip_pvt *p) |
Send SIP INFO with video update request. | |
static int | transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init) |
Build REFER/INVITE/OPTIONS message and transmit it. | |
static int | transmit_message_with_text (struct sip_pvt *p, const char *text) |
Transmit text with SIP MESSAGE method. | |
static int | transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten) |
Notify user of messages waiting in voicemail. | |
static int | transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate) |
Notify a transferring party of the status of transfer. | |
static int | transmit_refer (struct sip_pvt *p, const char *dest) |
Transmit SIP REFER message (initiated by the transfer() dialplan application. | |
static int | transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader) |
Transmit register to SIP proxy or UA. | |
static int | transmit_reinvite_with_sdp (struct sip_pvt *p) |
Transmit reinvite with SDP. | |
static int | transmit_reinvite_with_t38_sdp (struct sip_pvt *p) |
Transmit reinvite with T38 SDP We reinvite so that the T38 processing can take place. SIP Signalling stays with * in the path. | |
static int | transmit_request (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry). | |
static int | transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
Transmit SIP request, auth added. | |
static int | transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Transmit response, no retransmits. | |
static int | transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK. | |
static int | transmit_response_using_temp (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg) |
Transmit response, no retransmits, using a temporary pvt structure. | |
static int | transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Append Accept header, content length before transmitting response. | |
static int | transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale) |
Respond with authorization request. | |
static int | transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Append date and content length before transmitting response. | |
static int | transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Used for 200 OK and 183 early media. | |
static int | transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans) |
Used for 200 OK and 183 early media. | |
static int | transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported) |
Transmit response, no retransmits. | |
static int | transmit_sip_request (struct sip_pvt *p, struct sip_request *req) |
Transmit SIP request unreliably (only used in sip_notify subsystem). | |
static int | transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout) |
Used in the SUBSCRIBE notification subsystem. | |
static void | try_suggested_sip_codec (struct sip_pvt *p) |
Try setting codec suggested by the SIP_CODEC channel variable. | |
static int | unload_module (void) |
PBX unload module API. | |
static int | update_call_counter (struct sip_pvt *fup, int event) |
update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted. | |
static void | update_peer (struct sip_peer *p, int expiry) |
Update peer data in database (if used). | |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Session Initiation Protocol (SIP)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, .reload = reload, } |
static struct in_addr | __ourip |
static int | allow_external_domains |
static int | apeerobjs = 0 |
static char * | app_dtmfmode = "SIPDtmfMode" |
static char * | app_sipaddheader = "SIPAddHeader" |
static const struct ast_module_info * | ast_module_info = &__mod_info |
static struct sip_auth * | authl = NULL |
static int | autocreatepeer |
static struct sockaddr_in | bindaddr = { 0, } |
static struct ast_threadstorage | check_auth_buf = { .once = PTHREAD_ONCE_INIT , .key_init = check_auth_buf_init , } |
static struct ast_custom_function | checksipdomain_function |
static struct ast_cli_entry | cli_sip [] |
static struct ast_cli_entry | cli_sip_debug_deprecated |
static struct ast_cli_entry | cli_sip_no_debug_deprecated |
static int | compactheaders |
static const char | config [] = "sip.conf" |
static char | debug_usage [] |
static struct sockaddr_in | debugaddr |
static char | default_callerid [AST_MAX_EXTENSION] |
static char | default_context [AST_MAX_CONTEXT] |
static int | default_expiry = DEFAULT_DEFAULT_EXPIRY |
static char | default_fromdomain [AST_MAX_EXTENSION] |
static struct ast_jb_conf | default_jbconf |
Global jitterbuffer configuration - by default, jb is disabled. | |
static char | default_language [MAX_LANGUAGE] |
static int | default_maxcallbitrate |
static char | default_mohinterpret [MAX_MUSICCLASS] |
static char | default_mohsuggest [MAX_MUSICCLASS] |
static char | default_notifymime [AST_MAX_EXTENSION] |
static struct ast_codec_pref | default_prefs |
static int | default_qualify |
static char | default_subscribecontext [AST_MAX_CONTEXT] |
static char | default_vmexten [AST_MAX_EXTENSION] |
static char * | descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" |
static char * | descrip_sipaddheader |
static int | dumphistory |
static int | expiry = DEFAULT_EXPIRY |
static time_t | externexpire = 0 |
static char | externhost [MAXHOSTNAMELEN] |
static struct sockaddr_in | externip |
static int | externrefresh = 10 |
static int | global_allowguest |
static int | global_allowsubscribe |
static enum transfermodes | global_allowtransfer |
static int | global_alwaysauthreject |
static int | global_autoframing |
static int | global_callevents |
static int | global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 |
Codecs that we support by default:. | |
static struct ast_ha * | global_contact_ha = NULL |
Global list of addresses dynamic peers are not allowed to use. | |
static int | global_directrtpsetup |
static int | global_dynamic_exclude_static = 0 |
static struct ast_flags | global_flags [2] = {{0}} |
static struct ast_jb_conf | global_jbconf |
static int | global_limitonpeers |
static int | global_matchexterniplocally |
static int | global_mwitime |
static int | global_notifyhold |
static int | global_notifyringing |
static 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 ast_mutex_t | iflock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
Protect the SIP dialog list (of sip_pvt's). | |
static struct io_context * | io |
static struct ast_ha * | localaddr |
static char | mandescr_show_peer [] |
static char | mandescr_show_peers [] |
static int | max_expiry = DEFAULT_MAX_EXPIRY |
static int | min_expiry = DEFAULT_MIN_EXPIRY |
static pthread_t | monitor_thread = AST_PTHREADT_NULL |
This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
static ast_mutex_t | monlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static ast_mutex_t | netlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
static char | no_debug_usage [] |
static char | no_history_usage [] |
static const char | notify_config [] = "sip_notify.conf" |
static struct ast_config * | notify_types |
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 ast_mutex_t | sip_reload_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static char | sip_reload_usage [] |
static int | sip_reloading = FALSE |
static enum channelreloadreason | sip_reloadreason |
static struct ast_rtp_protocol | sip_rtp |
Interface structure with callbacks used to connect to RTP module. | |
static struct ast_channel_tech | sip_tech |
Definition of this channel for PBX channel registration. | |
static struct ast_channel_tech | sip_tech_info |
This version of the sip channel tech has no send_digit_begin callback. This is for use with channels using SIP INFO DTMF so that the core knows that the channel doesn't want DTMF BEGIN frames. | |
static struct ast_udptl_protocol | sip_udptl |
Interface structure with callbacks used to connect to UDPTL module. | |
static struct ast_custom_function | sipchaninfo_function |
Structure to declare a dialplan function: SIPCHANINFO. | |
ast_custom_function | sippeer_function |
Structure to declare a dialplan function: SIPPEER. | |
static int | sipsock = -1 |
static int * | sipsock_read_id |
static int | siptcpsock = -1 |
static int * | siptcpsock_read_id |
static int | speerobjs = 0 |
static int | srvlookup |
static struct cfsubscription_types | subscription_types [] |
static int | suserobjs = 0 |
static char * | synopsis_dtmfmode = "Change the dtmfmode for a SIP call" |
static char * | synopsis_sipaddheader = "Add a SIP header to the outbound call" |
static struct ast_threadstorage | ts_temp_pvt = { .once = PTHREAD_ONCE_INIT , .key_init = temp_pvt_init , } |
static struct ast_user_list | userl |
The user list: Users and friends. |
Better support of forking
VIA branch tag transaction checking
Transaction support
A new INVITE is sent to handle_request_invite(), that will end up starting a new channel in the PBX, the new channel after that executing in a separate channel thread. This is an incoming "call". When the call is answered, either by a bridged channel or the PBX itself the sip_answer() function is called.
The actual media - Video or Audio - is mostly handled by the RTP subsystem in rtp.c
Definition in file chan_sip.c.
#define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
SIP Methods we support.
Definition at line 475 of file chan_sip.c.
Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
#define append_history | ( | p, | |||
event, | |||||
fmt, | |||||
args... | ) | append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history.
Definition at line 1879 of file chan_sip.c.
Referenced by __sip_autodestruct(), __sip_reliable_xmit(), auto_congest(), build_reply_digest(), cb_extensionstate(), change_hold_state(), check_auth(), do_register_auth(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), local_attended_transfer(), retrans_pkt(), send_request(), send_response(), sip_cancel_destroy(), sip_fixup(), sip_hangup(), sip_new(), sip_park_thread(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), sipsock_read(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_with_auth().
#define CALLERID_UNKNOWN "Unknown" |
#define CAN_CREATE_DIALOG 1 |
Definition at line 368 of file chan_sip.c.
#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
Definition at line 369 of file chan_sip.c.
#define CAN_NOT_CREATE_DIALOG 0 |
Definition at line 367 of file chan_sip.c.
#define CHECK_AUTH_BUF_INITLEN 256 |
#define DEC_CALL_LIMIT 0 |
Definition at line 613 of file chan_sip.c.
Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_hangup(), and update_call_counter().
#define DEC_CALL_RINGING 2 |
Definition at line 615 of file chan_sip.c.
Referenced by handle_response_invite(), and update_call_counter().
#define DEFAULT_ALLOW_EXT_DOM TRUE |
Definition at line 507 of file chan_sip.c.
#define DEFAULT_ALLOWGUEST TRUE |
Definition at line 501 of file chan_sip.c.
#define DEFAULT_AUTOCREATEPEER FALSE |
Definition at line 511 of file chan_sip.c.
#define DEFAULT_CALLERID "asterisk" |
Definition at line 498 of file chan_sip.c.
#define DEFAULT_COMPACTHEADERS FALSE |
Definition at line 503 of file chan_sip.c.
#define DEFAULT_CONTEXT "default" |
Definition at line 494 of file chan_sip.c.
#define DEFAULT_DEFAULT_EXPIRY 120 |
Definition at line 171 of file chan_sip.c.
#define DEFAULT_EXPIRY 900 |
Expire slowly
Definition at line 188 of file chan_sip.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Qualification: How often to check, if the host is down...
Definition at line 203 of file chan_sip.c.
#define DEFAULT_FREQ_OK 60 * 1000 |
Qualification: How often to check for the host to be up
Definition at line 202 of file chan_sip.c.
#define DEFAULT_MAX_CALL_BITRATE (384) |
Max bitrate for video
Definition at line 514 of file chan_sip.c.
#define DEFAULT_MAX_EXPIRY 3600 |
Definition at line 173 of file chan_sip.c.
#define DEFAULT_MAX_FORWARDS "70" |
Definition at line 175 of file chan_sip.c.
Referenced by initreqprep(), reqprep(), and transmit_register().
#define DEFAULT_MAXMS 2000 |
Qualification: Must be faster than 2 seconds by default
Definition at line 201 of file chan_sip.c.
#define DEFAULT_MIN_EXPIRY 60 |
Definition at line 172 of file chan_sip.c.
#define DEFAULT_MOHINTERPRET "default" |
Definition at line 495 of file chan_sip.c.
#define DEFAULT_MOHSUGGEST "" |
Definition at line 496 of file chan_sip.c.
#define DEFAULT_MWITIME 10 |
Definition at line 500 of file chan_sip.c.
#define DEFAULT_NOTIFYMIME "application/simple-message-summary" |
Definition at line 499 of file chan_sip.c.
#define DEFAULT_NOTIFYRINGING TRUE |
Definition at line 509 of file chan_sip.c.
#define DEFAULT_PEDANTIC FALSE |
Definition at line 510 of file chan_sip.c.
#define DEFAULT_QUALIFY FALSE |
Definition at line 512 of file chan_sip.c.
#define DEFAULT_REALM "asterisk" |
Definition at line 508 of file chan_sip.c.
#define DEFAULT_REGISTRATION_TIMEOUT 20 |
Definition at line 174 of file chan_sip.c.
#define DEFAULT_RETRANS 1000 |
How frequently to retransmit Default: 2 * 500 ms in RFC 3261
Definition at line 205 of file chan_sip.c.
#define DEFAULT_SRVLOOKUP TRUE |
Recommended setting is ON
Definition at line 502 of file chan_sip.c.
#define DEFAULT_T1MIN 100 |
100 MS for minimal roundtrip time
Definition at line 513 of file chan_sip.c.
#define DEFAULT_TOS_AUDIO 0 |
Audio packets should be marked as DSCP EF (Expedited Forwarding), but the default is 0 to be compatible with previous versions.
Definition at line 505 of file chan_sip.c.
#define DEFAULT_TOS_SIP 0 |
Call signalling packets should be marked as DSCP CS3, but the default is 0 to be compatible with previous versions.
Definition at line 504 of file chan_sip.c.
#define DEFAULT_TOS_VIDEO 0 |
Video packets should be marked as DSCP AF41, but the default is 0 to be compatible with previous versions.
Definition at line 506 of file chan_sip.c.
#define DEFAULT_TRANS_TIMEOUT -1 |
Definition at line 210 of file chan_sip.c.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), and sip_send_mwi_to_peer().
#define DEFAULT_USERAGENT "Asterisk PBX" |
Default Useragent: header unless re-defined in sip.conf
Definition at line 516 of file chan_sip.c.
#define DEFAULT_VMEXTEN "asterisk" |
Definition at line 497 of file chan_sip.c.
#define EXPIRY_GUARD_LIMIT 30 |
Below here, we use EXPIRY_GUARD_PCT instead of EXPIRY_GUARD_SECS
Definition at line 180 of file chan_sip.c.
Referenced by handle_response_register().
#define EXPIRY_GUARD_MIN 500 |
This is the minimum guard time applied. If GUARD_PCT turns out to be lower than this, it will use this time instead. This is in milliseconds.
Definition at line 182 of file chan_sip.c.
Referenced by handle_response_register().
#define EXPIRY_GUARD_PCT 0.20 |
Percentage of expires timeout to use when below EXPIRY_GUARD_LIMIT
Definition at line 186 of file chan_sip.c.
Referenced by handle_response_register().
#define EXPIRY_GUARD_SECS 15 |
How long before expiry do we reregister
Definition at line 179 of file chan_sip.c.
Referenced by handle_response_register().
#define FALSE 0 |
Definition at line 153 of file chan_sip.c.
#define FLAG_FATAL (1 << 1) |
#define FLAG_RESPONSE (1 << 0) |
Definition at line 1039 of file chan_sip.c.
Referenced by __sip_ack(), __sip_pretend_ack(), __sip_reliable_xmit(), __sip_semi_ack(), handle_request(), and retrans_pkt().
#define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" |
#define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" |
#define FORMAT "%-40.40s %-20.20s %-16.16s\n" |
#define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" |
#define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
#define FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" |
#define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
#define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" |
#define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define FORMAT3H "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" |
Referenced by __sip_show_channels().
#define FORMAT3L "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" |
#define INC_CALL_LIMIT 1 |
Definition at line 614 of file chan_sip.c.
Referenced by handle_request_invite(), sip_hangup(), and update_call_counter().
#define INC_CALL_RINGING 3 |
#define INITIAL_CSEQ 101 |
our initial sip sequence number
Definition at line 219 of file chan_sip.c.
Referenced by sip_alloc(), sip_register(), and transmit_response_using_temp().
#define IPTOS_MINCOST 0x02 |
Definition at line 166 of file chan_sip.c.
#define MAX | ( | a, | |||
b | ) | ((a) > (b) ? (a) : (b)) |
Definition at line 196 of file chan_sip.c.
#define MAX_AUTHTRIES 3 |
Try authentication three times, then fail
Definition at line 211 of file chan_sip.c.
Referenced by handle_response(), handle_response_invite(), and handle_response_register().
#define MAX_HISTORY_ENTRIES 50 |
Max entires in the history list for a sip_pvt
Definition at line 1037 of file chan_sip.c.
Referenced by append_history_va().
#define MAX_RETRANS 6 |
Try only 6 times for retransmissions, a total of 7 transmissions
Definition at line 206 of file chan_sip.c.
#define NO_RTP 0 |
Definition at line 235 of file chan_sip.c.
#define NOT_SUPPORTED 0 |
Definition at line 408 of file chan_sip.c.
#define RTP 1 |
Definition at line 234 of file chan_sip.c.
#define SDP_MAX_RTPMAP_CODECS 32 |
Maximum number of codecs allowed in received SDP
Definition at line 217 of file chan_sip.c.
Referenced by process_sdp().
#define SDP_SAMPLE_RATE | ( | x | ) | 8000 |
Definition at line 6600 of file chan_sip.c.
Referenced by add_sdp().
#define SIP_ALREADYGONE (1 << 0) |
Whether or not we've already been destroyed by our peer
Definition at line 721 of file chan_sip.c.
Referenced by __sip_autodestruct(), handle_request(), handle_response_invite(), sip_alreadygone(), sip_hangup(), and sip_set_rtp_peer().
#define SIP_CALL_LIMIT (1 << 28) |
Call limit enforced for this call
Definition at line 762 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 750 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), sip_get_rtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), and sip_handle_t38_reinvite().
#define SIP_CAN_REINVITE_NAT (2 << 20) |
allow media reinvite when new peer is behind NAT
Definition at line 751 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 736 of file chan_sip.c.
Referenced by handle_invite_replaces(), handle_request_refer(), local_attended_transfer(), sip_hangup(), and sip_set_rtp_peer().
#define SIP_DTMF (3 << 16) |
DTMF Support: four settings, uses two bits
Definition at line 737 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 741 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 739 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 740 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 738 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().
#define SIP_FLAGS_TO_COPY |
Value:
(SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | \ SIP_PROG_INBAND | SIP_USECLIENTCODE | SIP_NAT | SIP_G726_NONSTANDARD | \ SIP_USEREQPHONE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE)
Definition at line 767 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 735 of file chan_sip.c.
#define SIP_G726_NONSTANDARD (1 << 31) |
Use non-standard packing for G726-32 data
Definition at line 765 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 728 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 764 of file chan_sip.c.
Referenced by __sip_destroy(), handle_request_cancel(), sip_hangup(), and update_call_counter().
#define SIP_INSECURE_INVITE (1 << 24) |
don't require authentication for incoming INVITEs
Definition at line 755 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), handle_common_options(), and set_insecure_flags().
#define SIP_INSECURE_PORT (1 << 23) |
don't require matching port for incoming requests
Definition at line 754 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), set_insecure_flags(), and sip_addrcmp().
#define SIP_MAX_HEADERS 64 |
Max amount of SIP headers to read
Definition at line 213 of file chan_sip.c.
Referenced by add_header(), and parse_request().
#define SIP_MAX_LINES 64 |
Max amount of lines in SIP attachment (like SDP)
Definition at line 214 of file chan_sip.c.
Referenced by add_line(), and parse_request().
#define SIP_MAX_PACKET 4096 |
Also from RFC 3261 (2543), should sub headers tho
Definition at line 215 of file chan_sip.c.
#define SIP_NAT (3 << 18) |
four settings, uses two bits
Definition at line 743 of file chan_sip.c.
Referenced by _sip_show_peer(), build_via(), copy_via_headers(), create_addr_from_peer(), handle_common_options(), process_sdp(), register_verify(), sip_alloc(), sip_nat_mode(), sip_real_dst(), sip_show_channel(), sip_show_settings(), sip_show_users(), and transmit_response_using_temp().
#define SIP_NAT_ALWAYS (3 << 18) |
NAT Both ROUTE and RFC3581
Definition at line 747 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 744 of file chan_sip.c.
Referenced by handle_common_options(), and nat2str().
#define SIP_NAT_RFC3581 (1 << 18) |
NAT RFC3581
Definition at line 745 of file chan_sip.c.
Referenced by build_via(), copy_via_headers(), handle_common_options(), and nat2str().
#define SIP_NAT_ROUTE (2 << 18) |
NAT Only ROUTE
Definition at line 746 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 722 of file chan_sip.c.
Referenced by __sip_autodestruct(), __sip_show_channels(), do_monitor(), handle_request(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), retrans_pkt(), sip_hangup(), sip_reg_timeout(), and sip_show_channel().
#define SIP_NEEDREINVITE (1 << 5) |
Do we need to send another reinvite?
Definition at line 726 of file chan_sip.c.
Referenced by check_pendings(), sip_handle_t38_reinvite(), sip_hangup(), sip_read(), sip_reinvite_retry(), sip_set_rtp_peer(), and sip_set_udptl_peer().
#define SIP_NO_HISTORY (1 << 27) |
Suppress recording request/response history
Definition at line 761 of file chan_sip.c.
Referenced by append_history_full(), do_register_auth(), handle_request_bye(), handle_request_invite(), send_request(), send_response(), sip_alloc(), sip_hangup(), sip_new(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), sipsock_read(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_using_temp().
#define SIP_NOVIDEO (1 << 2) |
Didn't get video in invite, don't offer
Definition at line 723 of file chan_sip.c.
Referenced by add_sdp(), process_sdp(), and sip_indicate().
#define SIP_OPT_100REL (1 << 1) |
Definition at line 411 of file chan_sip.c.
#define SIP_OPT_EARLY_SESSION (1 << 3) |
Definition at line 413 of file chan_sip.c.
#define SIP_OPT_EVENTLIST (1 << 11) |
Definition at line 421 of file chan_sip.c.
#define SIP_OPT_GRUU (1 << 12) |
Definition at line 422 of file chan_sip.c.
#define SIP_OPT_HISTINFO (1 << 15) |
Definition at line 425 of file chan_sip.c.
#define SIP_OPT_JOIN (1 << 4) |
Definition at line 414 of file chan_sip.c.
#define SIP_OPT_NOREFERSUB (1 << 14) |
Definition at line 424 of file chan_sip.c.
#define SIP_OPT_PATH (1 << 5) |
Definition at line 415 of file chan_sip.c.
#define SIP_OPT_PRECONDITION (1 << 7) |
Definition at line 417 of file chan_sip.c.
#define SIP_OPT_PREF (1 << 6) |
Definition at line 416 of file chan_sip.c.
#define SIP_OPT_PRIVACY (1 << 8) |
Definition at line 418 of file chan_sip.c.
#define SIP_OPT_REPLACES (1 << 0) |
#define SIP_OPT_RESPRIORITY (1 << 16) |
Definition at line 426 of file chan_sip.c.
#define SIP_OPT_SDP_ANAT (1 << 9) |
Definition at line 419 of file chan_sip.c.
#define SIP_OPT_SEC_AGREE (1 << 10) |
Definition at line 420 of file chan_sip.c.
#define SIP_OPT_TARGET_DIALOG (1 << 13) |
Definition at line 423 of file chan_sip.c.
#define SIP_OPT_TIMER (1 << 2) |
Definition at line 412 of file chan_sip.c.
#define SIP_OUTGOING (1 << 13) |
Direction of the last transaction in this dialog
Definition at line 734 of file chan_sip.c.
Referenced by handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), reqprep(), respprep(), sip_call(), sip_hangup(), sip_indicate(), sip_poke_peer(), sip_send_mwi_to_peer(), sip_show_channel(), sip_write(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_reinvite_with_t38_sdp(), and transmit_response_with_sdp().
#define SIP_PAGE2_ALLOWOVERLAP (1 << 17) |
Allow overlap dialing ?
Definition at line 789 of file chan_sip.c.
Referenced by _sip_show_peer(), get_destination(), handle_common_options(), handle_request_invite(), and sip_show_settings().
#define SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
Allow subscriptions from this peer?
Definition at line 788 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), build_user(), handle_common_options(), handle_request_subscribe(), and sip_show_settings().
#define SIP_PAGE2_BUGGY_MWI (1 << 26) |
26: Buggy CISCO MWI fix
Definition at line 801 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 796 of file chan_sip.c.
Referenced by __sip_destroy(), __sip_show_channels(), add_sdp(), change_hold_state(), handle_request_cancel(), handle_request_invite(), process_sdp(), sip_hangup(), and update_call_counter().
#define SIP_PAGE2_CALL_ONHOLD_ACTIVE (1 << 23) |
#define SIP_PAGE2_CALL_ONHOLD_INACTIVE (3 << 23) |
23: Inactive hold
Definition at line 799 of file chan_sip.c.
Referenced by add_sdp(), and change_hold_state().
#define SIP_PAGE2_CALL_ONHOLD_ONEDIR (2 << 23) |
23: One directional hold
Definition at line 798 of file chan_sip.c.
Referenced by add_sdp(), and change_hold_state().
#define SIP_PAGE2_DEBUG (3 << 11) |
Definition at line 782 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
Definition at line 783 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
Definition at line 784 of file chan_sip.c.
Referenced by sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), and sip_no_debug_deprecated().
#define SIP_PAGE2_DIALOG_ESTABLISHED (1 << 29) |
29: Has a dialog been established?
Definition at line 804 of file chan_sip.c.
Referenced by find_call(), handle_request_bye(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), and sip_answer().
#define SIP_PAGE2_DYNAMIC (1 << 13) |
Dynamic Peers register with Asterisk
Definition at line 785 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), function_sippeer(), register_verify(), and temp_peer().
#define SIP_PAGE2_FLAGS_TO_COPY |
Value:
(SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_VIDEOSUPPORT | \ SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | SIP_PAGE2_BUGGY_MWI | SIP_PAGE2_UDPTL_DESTINATION)
Definition at line 808 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 781 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 791 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 802 of file chan_sip.c.
Referenced by get_sip_pvt_byid_locked(), sip_request_call(), and update_call_counter().
#define SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) |
25: ????
Definition at line 800 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 777 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 774 of file chan_sip.c.
Referenced by build_peer(), complete_sip_prune_realtime_peer(), complete_sip_prune_realtime_user(), parse_register_contact(), sip_prune_realtime(), sip_show_settings(), update_call_counter(), and update_peer().
#define SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
Definition at line 778 of file chan_sip.c.
Referenced by realtime_update_peer(), and sip_show_settings().
#define SIP_PAGE2_RTUPDATE (1 << 1) |
#define SIP_PAGE2_SELFDESTRUCT (1 << 14) |
Automatic peers need to destruct themselves
Definition at line 786 of file chan_sip.c.
Referenced by expire_register(), sip_destroy_peer(), and temp_peer().
#define SIP_PAGE2_STATECHANGEQUEUE (1 << 9) |
D: Unsent state pending change exists
Definition at line 780 of file chan_sip.c.
Referenced by cb_extensionstate(), and handle_response().
#define SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
Only issue MWI notification if subscribed to
Definition at line 790 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 792 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 794 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 795 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 793 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), sip_read(), sip_rtp_read(), and sip_show_settings().
#define SIP_PAGE2_TCP (1 << 30) |
30: Should we use TCP with this peer
Definition at line 805 of file chan_sip.c.
Referenced by __sip_xmit(), _sip_show_peer(), build_via(), create_addr_from_peer(), parse_register_contact(), sip_poke_peer(), and sipsock_read().
#define SIP_PAGE2_TCP_CONNECTED (1 << 31) |
31: Is this TCP peer connected
Definition at line 806 of file chan_sip.c.
Referenced by __sip_xmit(), create_addr_from_peer(), expire_register(), parse_register_contact(), and sip_poke_peer().
#define SIP_PAGE2_UDPTL_DESTINATION (1 << 28) |
28: Use source IP of RTP as destination if NAT is enabled
Definition at line 803 of file chan_sip.c.
Referenced by handle_common_options(), and process_sdp().
#define SIP_PAGE2_VIDEOSUPPORT (1 << 15) |
Definition at line 787 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), check_user_full(), create_addr_from_peer(), handle_common_options(), sip_alloc(), and sip_show_settings().
#define SIP_PENDINGBYE (1 << 6) |
Need to send bye after we ack?
Definition at line 727 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 813 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 815 of file chan_sip.c.
Referenced by check_auth(), check_user_full(), handle_request(), handle_request_bye(), handle_request_invite(), handle_request_message(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), and register_verify().
#define SIP_PKT_IGNORE_REQ (1 << 4) |
#define SIP_PKT_IGNORE_RESP (1 << 3) |
#define SIP_PKT_WITH_TOTAG (1 << 1) |
This packet has a to-tag
Definition at line 814 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 757 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 759 of file chan_sip.c.
Referenced by handle_common_options(), and sip_show_settings().
#define SIP_PROG_INBAND_YES (2 << 25) |
Definition at line 760 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 725 of file chan_sip.c.
Referenced by sip_indicate(), and sip_write().
#define SIP_PROMISCREDIR (1 << 8) |
Promiscuous redirection
Definition at line 729 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 732 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), parse_register_contact(), sip_destroy_peer(), sip_destroy_user(), update_call_counter(), and update_peer().
#define SIP_REINVITE (7 << 20) |
#define SIP_REINVITE_UPDATE (4 << 20) |
use UPDATE (RFC3311) when reinviting this peer
Definition at line 752 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 763 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), and initreqprep().
#define SIP_TRANS_TIMEOUT 32000 |
SIP request timeout (rfc 3261) 64*T1
Definition at line 207 of file chan_sip.c.
Referenced by sip_call(), and sip_sipredirect().
#define SIP_TRUSTRPID (1 << 9) |
Trust RPID headers?
Definition at line 730 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 733 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 731 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), initreqprep(), and sip_show_settings().
#define SIPBUFSIZE 512 |
Definition at line 160 of file chan_sip.c.
Referenced by __sip_show_channels(), add_route(), add_sdp(), extract_uri(), handle_request_refer(), initreqprep(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), process_sdp(), respprep(), sip_call(), sip_new(), sip_show_channel(), sip_show_settings(), transmit_invite(), and transmit_notify_with_sipfrag().
#define sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG) |
Definition at line 845 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 846 of file chan_sip.c.
#define sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
Definition at line 847 of file chan_sip.c.
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
#define STANDARD_SIP_PORT 5060 |
Standard SIP port from RFC 3261. DO NOT CHANGE THIS.
Definition at line 481 of file chan_sip.c.
Referenced by __set_address_from_contact(), build_contact(), build_peer(), check_via(), create_addr(), initreqprep(), parse_register_contact(), set_destination(), set_peer_defaults(), sip_show_registry(), and transmit_register().
#define SUPPORTED 1 |
Define SIP option tags, used in Require: and Supported: headers We need to be aware of these properties in the phones to use the replace: header. We should not do that without knowing that the other end supports it... This is nothing we can configure, we learn by the dialog Supported: header on the REGISTER (peer) or the INVITE (other devices) We are not using many of these today, but will in the future. This is documented in RFC 3261
Definition at line 407 of file chan_sip.c.
#define SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support.
Definition at line 478 of file chan_sip.c.
Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
#define T38FAX_FILL_BIT_REMOVAL (1 << 0) |
Default: 0 (unset)
Definition at line 820 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 839 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 840 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 835 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 836 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 837 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 838 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 825 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
Definition at line 824 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 822 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 821 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 828 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 827 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 829 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 831 of file chan_sip.c.
Referenced by add_t38_sdp().
#define T38FAX_VERSION_0 (0 << 6) |
Version 0
Definition at line 832 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_VERSION_1 (1 << 6) |
Version 1
Definition at line 833 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define TRUE 1 |
Definition at line 157 of file chan_sip.c.
#define UNLINK | ( | element, | |||
head, | |||||
prev | ) |
--- some list management macros.
Definition at line 1625 of file chan_sip.c.
Referenced by __sip_ack(), and __sip_destroy().
#define VIDEO_CODEC_MASK 0x1fc0000 |
Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO
Definition at line 164 of file chan_sip.c.
#define XMIT_ERROR -2 |
Definition at line 162 of file chan_sip.c.
Referenced by __sip_reliable_xmit(), __sip_xmit(), handle_response_invite(), retrans_pkt(), sip_call(), and sip_poke_peer().
enum check_auth_result |
Authentication result from check_auth* functions.
AUTH_SUCCESSFUL | |
AUTH_CHALLENGE_SENT | |
AUTH_SECRET_FAILED | |
AUTH_USERNAME_MISMATCH | |
AUTH_NOT_FOUND | |
AUTH_FAKE_AUTH | |
AUTH_UNKNOWN_DOMAIN | |
AUTH_PEER_NOT_DYNAMIC | |
AUTH_ACL_FAILED |
Definition at line 343 of file chan_sip.c.
00343 { 00344 AUTH_SUCCESSFUL = 0, 00345 AUTH_CHALLENGE_SENT = 1, 00346 AUTH_SECRET_FAILED = -1, 00347 AUTH_USERNAME_MISMATCH = -2, 00348 AUTH_NOT_FOUND = -3, 00349 AUTH_FAKE_AUTH = -4, 00350 AUTH_UNKNOWN_DOMAIN = -5, 00351 AUTH_PEER_NOT_DYNAMIC = -6, 00352 AUTH_ACL_FAILED = -7, 00353 };
enum domain_mode |
Modes for SIP domain handling in the PBX.
SIP_DOMAIN_AUTO | This domain is auto-configured |
SIP_DOMAIN_CONFIG | This domain is from configuration |
Definition at line 684 of file chan_sip.c.
00684 { 00685 SIP_DOMAIN_AUTO, /*!< This domain is auto-configured */ 00686 SIP_DOMAIN_CONFIG, /*!< This domain is from configuration */ 00687 };
enum invitestates |
States for the INVITE transaction, not the dialog.
Definition at line 254 of file chan_sip.c.
00254 { 00255 INV_NONE = 0, /*!< No state at all, maybe not an INVITE dialog */ 00256 INV_CALLING = 1, /*!< Invite sent, no answer */ 00257 INV_PROCEEDING = 2, /*!< We got/sent 1xx message */ 00258 INV_EARLY_MEDIA = 3, /*!< We got/sent 18x message with to-tag back */ 00259 INV_COMPLETED = 4, /*!< Got final response with error. Wait for ACK, then CONFIRMED */ 00260 INV_CONFIRMED = 5, /*!< Confirmed response - we've got an ack (Incoming calls only) */ 00261 INV_TERMINATED = 6, /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done 00262 The only way out of this is a BYE from one side */ 00263 INV_CANCELLED = 7, /*!< Transaction cancelled by client or server in non-terminated state */ 00264 };
Definition at line 281 of file chan_sip.c.
00281 { 00282 PARSE_REGISTER_FAILED, 00283 PARSE_REGISTER_UPDATE, 00284 PARSE_REGISTER_QUERY, 00285 };
enum referstatus |
Parameters to know status of transfer.
Definition at line 869 of file chan_sip.c.
00869 { 00870 REFER_IDLE, /*!< No REFER is in progress */ 00871 REFER_SENT, /*!< Sent REFER to transferee */ 00872 REFER_RECEIVED, /*!< Received REFER from transferer */ 00873 REFER_CONFIRMED, /*!< Refer confirmed with a 100 TRYING */ 00874 REFER_ACCEPTED, /*!< Accepted by transferee */ 00875 REFER_RINGING, /*!< Target Ringing */ 00876 REFER_200OK, /*!< Answered by transfer target */ 00877 REFER_FAILED, /*!< REFER declined - go on */ 00878 REFER_NOAUTH /*!< We had no auth for REFER */ 00879 };
enum sip_auth_type |
Authentication types - proxy or www authentication.
Definition at line 337 of file chan_sip.c.
00337 { 00338 PROXY_AUTH, 00339 WWW_AUTH, 00340 };
enum sip_result |
Definition at line 246 of file chan_sip.c.
00246 { 00247 AST_SUCCESS = 0, 00248 AST_FAILURE = -1, 00249 };
enum sipmethod |
SIP Request methods known by Asterisk.
SIP_UNKNOWN | |
SIP_RESPONSE | |
SIP_REGISTER | |
SIP_OPTIONS | |
SIP_NOTIFY | |
SIP_INVITE | |
SIP_ACK | |
SIP_PRACK | |
SIP_BYE | |
SIP_REFER | |
SIP_SUBSCRIBE | |
SIP_MESSAGE | |
SIP_UPDATE | |
SIP_INFO | |
SIP_CANCEL | |
SIP_PUBLISH | |
SIP_PING |
Definition at line 312 of file chan_sip.c.
00312 { 00313 SIP_UNKNOWN, /* Unknown response */ 00314 SIP_RESPONSE, /* Not request, response to outbound request */ 00315 SIP_REGISTER, 00316 SIP_OPTIONS, 00317 SIP_NOTIFY, 00318 SIP_INVITE, 00319 SIP_ACK, 00320 SIP_PRACK, /* Not supported at all */ 00321 SIP_BYE, 00322 SIP_REFER, 00323 SIP_SUBSCRIBE, 00324 SIP_MESSAGE, 00325 SIP_UPDATE, /* We can send UPDATE; but not accept it */ 00326 SIP_INFO, 00327 SIP_CANCEL, 00328 SIP_PUBLISH, /* Not supported at all */ 00329 SIP_PING, /* Not supported at all, no standard but still implemented out there */ 00330 };
enum sipregistrystate |
States for outbound registrations (with register= lines in sip.conf.
Definition at line 356 of file chan_sip.c.
00356 { 00357 REG_STATE_UNREGISTERED = 0, /*!< We are not registred */ 00358 REG_STATE_REGSENT, /*!< Registration request sent */ 00359 REG_STATE_AUTHSENT, /*!< We have tried to authenticate */ 00360 REG_STATE_REGISTERED, /*!< Registred and done */ 00361 REG_STATE_REJECTED, /*!< Registration rejected */ 00362 REG_STATE_TIMEOUT, /*!< Registration timed out */ 00363 REG_STATE_NOAUTH, /*!< We have no accepted credentials */ 00364 REG_STATE_FAILED, /*!< Registration failed after several tries */ 00365 };
enum subscriptiontype |
Definition at line 287 of file chan_sip.c.
00287 { 00288 NONE = 0, 00289 XPIDF_XML, 00290 DIALOG_INFO_XML, 00291 CPIM_PIDF_XML, 00292 PIDF_XML, 00293 MWI_NOTIFICATION 00294 };
enum t38state |
T38 States for a call.
Definition at line 850 of file chan_sip.c.
00850 { 00851 T38_DISABLED = 0, /*!< Not enabled */ 00852 T38_LOCAL_DIRECT, /*!< Offered from local */ 00853 T38_LOCAL_REINVITE, /*!< Offered from local - REINVITE */ 00854 T38_PEER_DIRECT, /*!< Offered from peer */ 00855 T38_PEER_REINVITE, /*!< Offered from peer - REINVITE */ 00856 T38_ENABLED /*!< Negotiated (enabled) */ 00857 };
enum transfermodes |
Authorization scheme for call transfers.
Definition at line 240 of file chan_sip.c.
00240 { 00241 TRANSFER_OPENFORALL, /*!< Allow all SIP transfers */ 00242 TRANSFER_CLOSED, /*!< Allow no SIP transfers */ 00243 };
enum xmittype |
Definition at line 274 of file chan_sip.c.
00274 { 00275 XMIT_CRITICAL = 2, /*!< Transmit critical SIP message reliably, with re-transmits. 00276 If it fails, it's critical and will cause a teardown of the session */ 00277 XMIT_RELIABLE = 1, /*!< Transmit SIP message reliably, with re-transmits */ 00278 XMIT_UNRELIABLE = 0, /*!< Transmit SIP message without bothering with re-transmits */ 00279 };
static const char * __get_header | ( | const struct sip_request * | req, | |
const char * | name, | |||
int * | start | |||
) | [static] |
Definition at line 4355 of file chan_sip.c.
References ast_skip_blanks(), find_alias(), sip_request::header, sip_request::headers, and len().
04356 { 04357 int pass; 04358 04359 /* 04360 * Technically you can place arbitrary whitespace both before and after the ':' in 04361 * a header, although RFC3261 clearly says you shouldn't before, and place just 04362 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 04363 * a good idea to say you can do it, and if you can do it, why in the hell would. 04364 * you say you shouldn't. 04365 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 04366 * and we always allow spaces after that for compatibility. 04367 */ 04368 for (pass = 0; name && pass < 2;pass++) { 04369 int x, len = strlen(name); 04370 for (x=*start; x<req->headers; x++) { 04371 if (!strncasecmp(req->header[x], name, len)) { 04372 char *r = req->header[x] + len; /* skip name */ 04373 if (pedanticsipchecking) 04374 r = ast_skip_blanks(r); 04375 04376 if (*r == ':') { 04377 *start = x+1; 04378 return ast_skip_blanks(r+1); 04379 } 04380 } 04381 } 04382 if (pass == 0) /* Try aliases */ 04383 name = find_alias(name, NULL); 04384 } 04385 04386 /* Don't return NULL, so get_header is always a valid pointer */ 04387 return ""; 04388 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 19061 of file chan_sip.c.
static int __set_address_from_contact | ( | const char * | fullcontact, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 8227 of file chan_sip.c.
References ahp, ast_copy_string(), ast_gethostbyname(), ast_log(), hp, LOG_NOTICE, and STANDARD_SIP_PORT.
Referenced by build_peer(), and set_address_from_contact().
08228 { 08229 struct hostent *hp; 08230 struct ast_hostent ahp; 08231 int port; 08232 char *c, *host, *pt; 08233 char contact_buf[256]; 08234 char *contact; 08235 08236 /* Work on a copy */ 08237 ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf)); 08238 contact = contact_buf; 08239 08240 /* Make sure it's a SIP URL */ 08241 if (strncasecmp(contact, "sip:", 4)) { 08242 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 08243 } else 08244 contact += 4; 08245 08246 /* Ditch arguments */ 08247 /* XXX this code is replicated also shortly below */ 08248 08249 /* Grab host */ 08250 host = strchr(contact, '@'); 08251 if (!host) { /* No username part */ 08252 host = contact; 08253 c = NULL; 08254 } else { 08255 *host++ = '\0'; 08256 } 08257 pt = strchr(host, ':'); 08258 if (pt) { 08259 *pt++ = '\0'; 08260 port = atoi(pt); 08261 } else 08262 port = STANDARD_SIP_PORT; 08263 08264 contact = strsep(&contact, ";"); /* trim ; and beyond in username part */ 08265 host = strsep(&host, ";"); /* trim ; and beyond in host/domain part */ 08266 08267 /* XXX This could block for a long time XXX */ 08268 /* We should only do this if it's a name, not an IP */ 08269 hp = ast_gethostbyname(host, &ahp); 08270 if (!hp) { 08271 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 08272 return -1; 08273 } 08274 sin->sin_family = AF_INET; 08275 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 08276 sin->sin_port = htons(port); 08277 08278 return 0; 08279 }
static void __sip_ack | ( | struct sip_pvt * | p, | |
int | seqno, | |||
int | resp, | |||
int | sipmethod | |||
) | [static] |
Acknowledges receipt of a packet and stops retransmission called with p locked.
Definition at line 2186 of file chan_sip.c.
References ast_log(), ast_sched_del(), ast_test_flag, sip_pvt::callid, sip_pkt::data, DEADLOCK_AVOIDANCE, FALSE, FLAG_RESPONSE, free, sip_pvt::lock, LOG_DEBUG, sip_pkt::next, option_debug, sip_pvt::packets, sip_pvt::pendinginvite, sip_pkt::retransid, sched, sip_pkt::seqno, sip_methods, sipdebug, cfsip_methods::text, TRUE, and UNLINK.
Referenced by __sip_pretend_ack(), handle_request(), and handle_response().
02187 { 02188 struct sip_pkt *cur, *prev = NULL; 02189 02190 /* Just in case... */ 02191 char *msg; 02192 int res = FALSE; 02193 02194 msg = sip_methods[sipmethod].text; 02195 02196 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 02197 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 02198 ((ast_test_flag(cur, FLAG_RESPONSE)) || 02199 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 02200 if (!resp && (seqno == p->pendinginvite)) { 02201 if (option_debug) 02202 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 02203 p->pendinginvite = 0; 02204 } 02205 /* this is our baby */ 02206 res = TRUE; 02207 UNLINK(cur, p->packets, prev); 02208 if (cur->retransid > -1) { 02209 if (sipdebug && option_debug > 3) 02210 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 02211 } 02212 /* This odd section is designed to thwart a 02213 * race condition in the packet scheduler. There are 02214 * two conditions under which deleting the packet from the 02215 * scheduler can fail. 02216 * 02217 * 1. The packet has been removed from the scheduler because retransmission 02218 * is being attempted. The problem is that if the packet is currently attempting 02219 * retransmission and we are at this point in the code, then that MUST mean 02220 * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the 02221 * lock temporarily to allow retransmission. 02222 * 02223 * 2. The packet has reached its maximum number of retransmissions and has 02224 * been permanently removed from the packet scheduler. If this is the case, then 02225 * the packet's retransid will be set to -1. The atomicity of the setting and checking 02226 * of the retransid to -1 is ensured since in both cases p's lock is held. 02227 */ 02228 while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) { 02229 DEADLOCK_AVOIDANCE(&p->lock); 02230 } 02231 free(cur); 02232 break; 02233 } 02234 } 02235 if (option_debug) 02236 ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res == FALSE ? "Not Found" : "Found"); 02237 }
static int __sip_autodestruct | ( | const void * | data | ) | [static] |
Kill a SIP dialog (called by scheduler).
Definition at line 2102 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup(), ast_set_flag, ast_test_flag, ASTOBJ_UNREF, sip_pvt::autokillid, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, LOG_DEBUG, LOG_WARNING, sip_pvt::method, NONE, option_debug, sip_pvt::owner, sip_pvt::packets, sip_pvt::refer, sip_pvt::relatedpeer, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_destroy(), sip_destroy_peer(), sip_methods, SIP_NEEDDESTROY, sip_scheddestroy(), sip_pvt::subscribed, transmit_request_with_auth(), transmit_state_notify(), TRUE, and XMIT_RELIABLE.
Referenced by sip_scheddestroy().
02103 { 02104 struct sip_pvt *p = (struct sip_pvt *)data; 02105 02106 /* If this is a subscription, tell the phone that we got a timeout */ 02107 if (p->subscribed) { 02108 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 02109 p->subscribed = NONE; 02110 append_history(p, "Subscribestatus", "timeout"); 02111 if (option_debug > 2) 02112 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>"); 02113 return 10000; /* Reschedule this destruction so that we know that it's gone */ 02114 } 02115 02116 /* If there are packets still waiting for delivery, delay the destruction */ 02117 /* via bug 12101, the two usages of SIP_NEEDDESTROY in the following block 02118 * of code make a sort of "safety relief valve", that allows sip channels 02119 * that were created via INVITE, then thru some sequence were CANCELED, 02120 * to die, rather than infinitely be rescheduled */ 02121 if (p->packets && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 02122 if (option_debug > 2) 02123 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>"); 02124 append_history(p, "ReliableXmit", "timeout"); 02125 if (p->method == SIP_CANCEL || p->method == SIP_BYE) { 02126 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 02127 } 02128 return 10000; 02129 } 02130 02131 /* If we're destroying a subscription, dereference peer object too */ 02132 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 02133 ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer); 02134 02135 /* Reset schedule ID */ 02136 p->autokillid = -1; 02137 02138 if (option_debug) 02139 ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid); 02140 append_history(p, "AutoDestroy", "%s", p->callid); 02141 if (p->owner) { 02142 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 02143 ast_queue_hangup(p->owner); 02144 } else if (p->refer && !ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 02145 if (option_debug > 2) 02146 ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid); 02147 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 02148 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 02149 } else 02150 sip_destroy(p); 02151 return 0; 02152 }
static int __sip_destroy | ( | struct sip_pvt * | p, | |
int | lockowner | |||
) | [static] |
Execute destruction of SIP dialog structure, release memory.
Definition at line 3123 of file chan_sip.c.
References ast_channel::_softhangup, ast_channel_lock, ast_channel_unlock, ast_extension_state_del(), ast_free, AST_LIST_REMOVE_HEAD, ast_log(), ast_rtp_destroy(), ast_rtp_get_bridged(), AST_SCHED_DEL, AST_SOFTHANGUP_DEV, ast_test_flag, ast_udptl_destroy(), ast_verbose(), ASTOBJ_UNREF, sip_pvt::callid, DEC_CALL_LIMIT, sip_pvt::flags, free, free_old_route(), iflist, sip_history::list, LOG_DEBUG, sip_pvt::method, sip_peer::mwipvt, ast_channel::name, sip_pvt::next, sip_history::next, option_debug, sip_pvt::owner, sip_pvt::relatedpeer, sip_pkt::retransid, sip_pvt::rtp, sched, sip_debug_test_pvt(), sip_destroy_peer(), sip_dump_history(), SIP_INC_COUNT, sip_methods, SIP_PAGE2_CALL_ONHOLD, sip_registry_destroy(), ast_channel::tech_pvt, UNLINK, update_call_counter(), and sip_pvt::vrtp.
Referenced by do_monitor(), sip_destroy(), and unload_module().
03124 { 03125 struct sip_pvt *cur, *prev = NULL; 03126 struct sip_pkt *cp; 03127 struct sip_request *req; 03128 03129 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 03130 if (p->rtp && ast_rtp_get_bridged(p->rtp)) { 03131 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03132 return -1; 03133 } 03134 03135 if (p->vrtp && ast_rtp_get_bridged(p->vrtp)) { 03136 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03137 return -1; 03138 } 03139 03140 if (sip_debug_test_pvt(p) || option_debug > 2) 03141 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03142 03143 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03144 update_call_counter(p, DEC_CALL_LIMIT); 03145 if (option_debug > 1) 03146 ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 03147 } 03148 03149 /* Unlink us from the owner if we have one */ 03150 if (p->owner) { 03151 if (lockowner) 03152 ast_channel_lock(p->owner); 03153 if (option_debug) 03154 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 03155 p->owner->tech_pvt = NULL; 03156 /* Make sure that the channel knows its backend is going away */ 03157 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03158 if (lockowner) 03159 ast_channel_unlock(p->owner); 03160 /* Give the channel a chance to react before deallocation */ 03161 usleep(1); 03162 } 03163 03164 /* Remove link from peer to subscription of MWI */ 03165 if (p->relatedpeer) { 03166 if (p->relatedpeer->mwipvt == p) { 03167 p->relatedpeer->mwipvt = NULL; 03168 } 03169 ASTOBJ_UNREF(p->relatedpeer, sip_destroy_peer); 03170 } 03171 03172 if (dumphistory) 03173 sip_dump_history(p); 03174 03175 if (p->options) 03176 free(p->options); 03177 03178 if (p->stateid > -1) 03179 ast_extension_state_del(p->stateid, NULL); 03180 AST_SCHED_DEL(sched, p->initid); 03181 AST_SCHED_DEL(sched, p->waitid); 03182 AST_SCHED_DEL(sched, p->autokillid); 03183 AST_SCHED_DEL(sched, p->request_queue_sched_id); 03184 03185 if (p->rtp) { 03186 ast_rtp_destroy(p->rtp); 03187 } 03188 if (p->vrtp) { 03189 ast_rtp_destroy(p->vrtp); 03190 } 03191 if (p->udptl) 03192 ast_udptl_destroy(p->udptl); 03193 if (p->refer) 03194 free(p->refer); 03195 if (p->route) { 03196 free_old_route(p->route); 03197 p->route = NULL; 03198 } 03199 if (p->registry) { 03200 if (p->registry->call == p) 03201 p->registry->call = NULL; 03202 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 03203 } 03204 03205 /* Clear history */ 03206 if (p->history) { 03207 struct sip_history *hist; 03208 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 03209 free(hist); 03210 p->history_entries--; 03211 } 03212 free(p->history); 03213 p->history = NULL; 03214 } 03215 03216 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 03217 ast_free(req); 03218 } 03219 03220 for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) { 03221 if (cur == p) { 03222 UNLINK(cur, iflist, prev); 03223 break; 03224 } 03225 } 03226 if (!cur) { 03227 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 03228 return 0; 03229 } 03230 03231 /* remove all current packets in this dialog */ 03232 while((cp = p->packets)) { 03233 p->packets = p->packets->next; 03234 AST_SCHED_DEL(sched, cp->retransid); 03235 free(cp); 03236 } 03237 if (p->chanvars) { 03238 ast_variables_destroy(p->chanvars); 03239 p->chanvars = NULL; 03240 } 03241 ast_mutex_destroy(&p->lock); 03242 03243 ast_string_field_free_memory(p); 03244 03245 free(p); 03246 return 0; 03247 }
static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 7656 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
07657 { 07658 int res; 07659 07660 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 07661 return res; 07662 }
static void __sip_pretend_ack | ( | struct sip_pvt * | p | ) | [static] |
Pretend to ack all packets called with p locked.
Definition at line 2241 of file chan_sip.c.
References __sip_ack(), ast_log(), ast_test_flag, sip_pkt::data, find_sip_method(), FLAG_RESPONSE, LOG_WARNING, sip_pkt::method, sip_request::method, sip_pvt::packets, sip_pkt::seqno, and sip_methods.
Referenced by handle_request_bye(), handle_request_cancel(), sip_hangup(), and sip_reg_timeout().
02242 { 02243 struct sip_pkt *cur = NULL; 02244 02245 while (p->packets) { 02246 int method; 02247 if (cur == p->packets) { 02248 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 02249 return; 02250 } 02251 cur = p->packets; 02252 method = (cur->method) ? cur->method : find_sip_method(cur->data); 02253 __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method); 02254 } 02255 }
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 2055 of file chan_sip.c.
References __sip_xmit(), append_history, ast_calloc, AST_FAILURE, ast_log(), ast_sched_add_variable(), ast_set_flag, AST_SUCCESS, ast_test_flag, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, LOG_DEBUG, option_debug, sip_pkt::owner, sip_pvt::packets, sip_pvt::pendinginvite, retrans_pkt(), sched, SIP_INVITE, sipdebug, sip_pvt::timer_t1, and XMIT_ERROR.
Referenced by send_request(), and send_response().
02056 { 02057 struct sip_pkt *pkt; 02058 int siptimer_a = DEFAULT_RETRANS; 02059 int xmitres = 0; 02060 02061 if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) 02062 return AST_FAILURE; 02063 memcpy(pkt->data, data, len); 02064 pkt->method = sipmethod; 02065 pkt->packetlen = len; 02066 pkt->next = p->packets; 02067 pkt->owner = p; 02068 pkt->seqno = seqno; 02069 if (resp) 02070 ast_set_flag(pkt, FLAG_RESPONSE); 02071 pkt->data[len] = '\0'; 02072 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 02073 pkt->retransid = -1; 02074 if (fatal) 02075 ast_set_flag(pkt, FLAG_FATAL); 02076 if (pkt->timer_t1) 02077 siptimer_a = pkt->timer_t1 * 2; 02078 02079 if (option_debug > 3 && sipdebug) 02080 ast_log(LOG_DEBUG, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid); 02081 pkt->retransid = -1; 02082 pkt->next = p->packets; 02083 p->packets = pkt; 02084 if (sipmethod == SIP_INVITE) { 02085 /* Note this is a pending invite */ 02086 p->pendinginvite = seqno; 02087 } 02088 02089 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 02090 02091 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 02092 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02093 return AST_FAILURE; 02094 } else { 02095 /* Schedule retransmission */ 02096 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 02097 return AST_SUCCESS; 02098 } 02099 }
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 2258 of file chan_sip.c.
References ast_log(), AST_SCHED_DEL, ast_test_flag, sip_pvt::callid, 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().
02259 { 02260 struct sip_pkt *cur; 02261 int res = -1; 02262 02263 for (cur = p->packets; cur; cur = cur->next) { 02264 if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp && 02265 (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) { 02266 /* this is our baby */ 02267 if (cur->retransid > -1) { 02268 if (option_debug > 3 && sipdebug) 02269 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 02270 } 02271 AST_SCHED_DEL(sched, cur->retransid); 02272 res = 0; 02273 break; 02274 } 02275 } 02276 if (option_debug) 02277 ast_log(LOG_DEBUG, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res == -1 ? "Not Found" : "Found"); 02278 return res; 02279 }
static int __sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[], | |||
int | subscriptions | |||
) | [static] |
SIP show channels CLI (main function).
Definition at line 11069 of file chan_sip.c.
References ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_test_flag, sip_pvt::callid, sip_pvt::cid_num, sip_pvt::flags, FORMAT, FORMAT2, FORMAT3H, sip_pvt::icseq, iflist, iflock, sip_pvt::lastmsg, ast_channel::nativeformats, sip_pvt::next, NONE, sip_pvt::ocseq, sip_pvt::owner, sip_pvt::refer, referstatus2str(), RESULT_SHOWUSAGE, S_OR, sip_pvt::sa, SIP_NEEDDESTROY, SIP_PAGE2_CALL_ONHOLD, SIPBUFSIZE, sip_refer::status, sip_pvt::subscribed, and sip_pvt::username.
Referenced by sip_show_channels(), and sip_show_subscriptions().
11070 { 11071 #define FORMAT3L "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" 11072 #define FORMAT3H "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" 11073 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" 11074 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" 11075 struct sip_pvt *cur; 11076 int numchans = 0; 11077 char *referstatus = NULL; 11078 11079 if (argc != 3) 11080 return RESULT_SHOWUSAGE; 11081 ast_mutex_lock(&iflock); 11082 cur = iflist; 11083 if (!subscriptions) 11084 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 11085 else 11086 ast_cli(fd, FORMAT3H, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry"); 11087 for (; cur; cur = cur->next) { 11088 referstatus = ""; 11089 if (cur->refer) { /* SIP transfer in progress */ 11090 referstatus = referstatus2str(cur->refer->status); 11091 } 11092 if (cur->subscribed == NONE && !subscriptions) { 11093 char formatbuf[SIPBUFSIZE/2]; 11094 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 11095 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 11096 cur->callid, 11097 cur->ocseq, cur->icseq, 11098 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 11099 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 11100 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 11101 cur->lastmsg , 11102 referstatus 11103 ); 11104 numchans++; 11105 } 11106 if (cur->subscribed != NONE && subscriptions) { 11107 ast_cli(fd, FORMAT3L, ast_inet_ntoa(cur->sa.sin_addr), 11108 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 11109 cur->callid, 11110 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 11111 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 11112 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 11113 subscription_type2str(cur->subscribed), 11114 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>", 11115 cur->expiry 11116 ); 11117 numchans++; 11118 } 11119 } 11120 ast_mutex_unlock(&iflock); 11121 if (!subscriptions) 11122 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 11123 else 11124 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 11125 return RESULT_SUCCESS; 11126 #undef FORMAT 11127 #undef FORMAT2 11128 #undef FORMAT3 11129 }
static int __sip_xmit | ( | struct sip_pvt * | p, | |
char * | data, | |||
int | len | |||
) | [static] |
Transmit SIP message.
Definition at line 1792 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_set_flag, ast_test_flag, errno, sip_pvt::flags, LOG_ERROR, LOG_WARNING, SIP_PAGE2_TCP, SIP_PAGE2_TCP_CONNECTED, sip_real_dst(), sipsock, sip_pvt::sockfd, and XMIT_ERROR.
Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response().
01793 { 01794 int res; 01795 const struct sockaddr_in *dst = sip_real_dst(p); 01796 /* This is a TCP connection*/ 01797 if (ast_test_flag(&p->flags[1], SIP_PAGE2_TCP)) { 01798 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_TCP_CONNECTED)) { 01799 if (connect(p->sockfd, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)) == 0) { 01800 ast_set_flag(&p->flags[1], SIP_PAGE2_TCP_CONNECTED); 01801 } else if (errno == EISCONN) { 01802 ast_set_flag(&p->flags[1], SIP_PAGE2_TCP_CONNECTED); 01803 } else { 01804 ast_log(LOG_ERROR, "Connect Failed Sock: %i %s:%d %s\n",p->sockfd,ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), strerror(errno)); 01805 } 01806 } 01807 res = write(p->sockfd, data, len); 01808 } else 01809 res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)); 01810 01811 if (res == -1) { 01812 switch (errno) { 01813 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 01814 case EHOSTUNREACH: /* Host can't be reached */ 01815 case ENETDOWN: /* Inteface down */ 01816 case ENETUNREACH: /* Network failure */ 01817 case ECONNREFUSED: /* ICMP port unreachable */ 01818 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 01819 } 01820 } 01821 if (res != len) 01822 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)); 01823 return res; 01824 }
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 6191 of file chan_sip.c.
References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), get_header(), ast_channel::hangupcause, sip_pvt::method, sip_pvt::owner, respprep(), send_response(), and SIP_INVITE.
Referenced by transmit_response(), transmit_response_reliable(), and transmit_response_using_temp().
06192 { 06193 struct sip_request resp; 06194 int seqno = 0; 06195 06196 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06197 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06198 return -1; 06199 } 06200 respprep(&resp, p, msg, req); 06201 add_header_contentLength(&resp, 0); 06202 /* If we are cancelling an incoming invite for some reason, add information 06203 about the reason why we are doing this in clear text */ 06204 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 06205 char buf[10]; 06206 06207 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 06208 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 06209 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 06210 } 06211 return send_response(p, &resp, reliable, seqno); 06212 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 19061 of file chan_sip.c.
static int _sip_show_peer | ( | int | type, | |
int | fd, | |||
struct mansession * | s, | |||
const struct message * | m, | |||
int | argc, | |||
const char * | argv[] | |||
) | [static] |
Show one peer in detail (main function).
Definition at line 10626 of file chan_sip.c.
References sip_peer::accountcode, sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_check_realtime(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_print_group(), ast_sched_when(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, dtmfmode2str(), sip_peer::expire, FALSE, find_peer(), sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, insecure2str(), sip_peer::language, sip_peer::lastmsg, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_auth::md5secret, sip_peer::md5secret, ast_variable::name, sip_peer::name, nat2str(), ast_variable::next, sip_auth::next, peer_status(), sip_peer::pickupgroup, sip_peer::prefs, print_codec_to_cli(), print_group(), sip_auth::realm, sip_peer::regexten, RESULT_SHOWUSAGE, RESULT_SUCCESS, s, S_OR, sched, sip_auth::secret, sip_peer::secret, SIP_CAN_REINVITE, sip_destroy_peer(), SIP_DTMF, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, sip_options, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_TCP, SIP_PAGE2_VIDEOSUPPORT, SIP_PROMISCREDIR, SIP_REALTIME, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USEREQPHONE, sip_peer::sipoptions, sip_peer::subscribecontext, text, sip_peer::tohost, transfermode2str(), TRUE, sip_peer::useragent, sip_peer::username, sip_auth::username, ast_variable::value, and sip_peer::vmexten.
Referenced by manager_sip_show_peer(), and sip_show_peer().
10627 { 10628 char status[30] = ""; 10629 char cbuf[256]; 10630 struct sip_peer *peer; 10631 char codec_buf[512]; 10632 struct ast_codec_pref *pref; 10633 struct ast_variable *v; 10634 struct sip_auth *auth; 10635 int x = 0, codec = 0, load_realtime; 10636 int realtimepeers; 10637 10638 realtimepeers = ast_check_realtime("sippeers"); 10639 10640 if (argc < 4) 10641 return RESULT_SHOWUSAGE; 10642 10643 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10644 peer = find_peer(argv[3], NULL, load_realtime, 0); 10645 if (s) { /* Manager */ 10646 if (peer) { 10647 const char *id = astman_get_header(m,"ActionID"); 10648 10649 astman_append(s, "Response: Success\r\n"); 10650 if (!ast_strlen_zero(id)) 10651 astman_append(s, "ActionID: %s\r\n",id); 10652 } else { 10653 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]); 10654 astman_send_error(s, m, cbuf); 10655 return 0; 10656 } 10657 } 10658 if (peer && type==0 ) { /* Normal listing */ 10659 ast_cli(fd,"\n\n"); 10660 ast_cli(fd, " * Name : %s\n", peer->name); 10661 if (realtimepeers) { /* Realtime is enabled */ 10662 ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 10663 } 10664 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 10665 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 10666 for (auth = peer->auth; auth; auth = auth->next) { 10667 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 10668 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 10669 } 10670 ast_cli(fd, " Context : %s\n", peer->context); 10671 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 10672 ast_cli(fd, " Language : %s\n", peer->language); 10673 if (!ast_strlen_zero(peer->accountcode)) 10674 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 10675 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 10676 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 10677 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 10678 if (!ast_strlen_zero(peer->fromuser)) 10679 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 10680 if (!ast_strlen_zero(peer->fromdomain)) 10681 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 10682 ast_cli(fd, " Callgroup : "); 10683 print_group(fd, peer->callgroup, 0); 10684 ast_cli(fd, " Pickupgroup : "); 10685 print_group(fd, peer->pickupgroup, 0); 10686 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 10687 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 10688 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 10689 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 10690 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 10691 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 10692 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 10693 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 10694 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))); 10695 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10696 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 10697 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 10698 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10699 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 10700 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 10701 #endif 10702 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 10703 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 10704 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 10705 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 10706 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 10707 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 10708 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10709 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10710 10711 /* - is enumerated */ 10712 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10713 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 10714 ast_cli(fd, " ToHost : %s\n", peer->tohost); 10715 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)); 10716 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 10717 ast_cli(fd, " Transport : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_TCP) ? "TCP" : "UDP"); 10718 if (!ast_strlen_zero(global_regcontext)) 10719 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 10720 ast_cli(fd, " Def. Username: %s\n", peer->username); 10721 ast_cli(fd, " SIP Options : "); 10722 if (peer->sipoptions) { 10723 int lastoption = -1; 10724 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10725 if (sip_options[x].id != lastoption) { 10726 if (peer->sipoptions & sip_options[x].id) 10727 ast_cli(fd, "%s ", sip_options[x].text); 10728 lastoption = x; 10729 } 10730 } 10731 } else 10732 ast_cli(fd, "(none)"); 10733 10734 ast_cli(fd, "\n"); 10735 ast_cli(fd, " Codecs : "); 10736 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10737 ast_cli(fd, "%s\n", codec_buf); 10738 ast_cli(fd, " Codec Order : ("); 10739 print_codec_to_cli(fd, &peer->prefs); 10740 ast_cli(fd, ")\n"); 10741 10742 ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No"); 10743 ast_cli(fd, " Status : "); 10744 peer_status(peer, status, sizeof(status)); 10745 ast_cli(fd, "%s\n",status); 10746 ast_cli(fd, " Useragent : %s\n", peer->useragent); 10747 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 10748 if (peer->chanvars) { 10749 ast_cli(fd, " Variables :\n"); 10750 for (v = peer->chanvars ; v ; v = v->next) 10751 ast_cli(fd, " %s = %s\n", v->name, v->value); 10752 } 10753 ast_cli(fd,"\n"); 10754 ASTOBJ_UNREF(peer,sip_destroy_peer); 10755 } else if (peer && type == 1) { /* manager listing */ 10756 char buf[256]; 10757 astman_append(s, "Channeltype: SIP\r\n"); 10758 astman_append(s, "ObjectName: %s\r\n", peer->name); 10759 astman_append(s, "ChanObjectType: peer\r\n"); 10760 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 10761 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 10762 astman_append(s, "Context: %s\r\n", peer->context); 10763 astman_append(s, "Language: %s\r\n", peer->language); 10764 if (!ast_strlen_zero(peer->accountcode)) 10765 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 10766 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 10767 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 10768 if (!ast_strlen_zero(peer->fromuser)) 10769 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 10770 if (!ast_strlen_zero(peer->fromdomain)) 10771 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 10772 astman_append(s, "Callgroup: "); 10773 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup)); 10774 astman_append(s, "Pickupgroup: "); 10775 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup)); 10776 astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox); 10777 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 10778 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 10779 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 10780 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 10781 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 10782 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 10783 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 10784 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))); 10785 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10786 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 10787 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 10788 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 10789 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 10790 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 10791 10792 /* - is enumerated */ 10793 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10794 astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg); 10795 astman_append(s, "ToHost: %s\r\n", peer->tohost); 10796 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)); 10797 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)); 10798 astman_append(s, "Default-Username: %s\r\n", peer->username); 10799 if (!ast_strlen_zero(global_regcontext)) 10800 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 10801 astman_append(s, "Codecs: "); 10802 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10803 astman_append(s, "%s\r\n", codec_buf); 10804 astman_append(s, "CodecOrder: "); 10805 pref = &peer->prefs; 10806 for(x = 0; x < 32 ; x++) { 10807 codec = ast_codec_pref_index(pref,x); 10808 if (!codec) 10809 break; 10810 astman_append(s, "%s", ast_getformatname(codec)); 10811 if (x < 31 && ast_codec_pref_index(pref,x+1)) 10812 astman_append(s, ","); 10813 } 10814 10815 astman_append(s, "\r\n"); 10816 astman_append(s, "Status: "); 10817 peer_status(peer, status, sizeof(status)); 10818 astman_append(s, "%s\r\n", status); 10819 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 10820 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 10821 if (peer->chanvars) { 10822 for (v = peer->chanvars ; v ; v = v->next) { 10823 astman_append(s, "ChanVariable:\n"); 10824 astman_append(s, " %s,%s\r\n", v->name, v->value); 10825 } 10826 } 10827 10828 ASTOBJ_UNREF(peer,sip_destroy_peer); 10829 10830 } else { 10831 ast_cli(fd,"Peer %s not found.\n", argv[3]); 10832 ast_cli(fd,"\n"); 10833 } 10834 10835 return RESULT_SUCCESS; 10836 }
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 10176 of file chan_sip.c.
References ast_check_realtime(), ast_cli(), ast_copy_string(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, FORMAT2, id, name, peer_status(), peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, s, SIP_NAT_ROUTE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_VIDEOSUPPORT, SIP_REALTIME, and TRUE.
Referenced by manager_sip_show_peers(), and sip_show_peers().
10177 { 10178 regex_t regexbuf; 10179 int havepattern = FALSE; 10180 10181 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 10182 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 10183 10184 char name[256]; 10185 int total_peers = 0; 10186 int peers_mon_online = 0; 10187 int peers_mon_offline = 0; 10188 int peers_unmon_offline = 0; 10189 int peers_unmon_online = 0; 10190 const char *id; 10191 char idtext[256] = ""; 10192 int realtimepeers; 10193 10194 realtimepeers = ast_check_realtime("sippeers"); 10195 10196 if (s) { /* Manager - get ActionID */ 10197 id = astman_get_header(m,"ActionID"); 10198 if (!ast_strlen_zero(id)) 10199 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 10200 } 10201 10202 switch (argc) { 10203 case 5: 10204 if (!strcasecmp(argv[3], "like")) { 10205 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 10206 return RESULT_SHOWUSAGE; 10207 havepattern = TRUE; 10208 } else 10209 return RESULT_SHOWUSAGE; 10210 case 3: 10211 break; 10212 default: 10213 return RESULT_SHOWUSAGE; 10214 } 10215 10216 if (!s) /* Normal list */ 10217 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 10218 10219 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10220 char status[20] = ""; 10221 char srch[2000]; 10222 char pstatus; 10223 10224 ASTOBJ_RDLOCK(iterator); 10225 10226 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10227 ASTOBJ_UNLOCK(iterator); 10228 continue; 10229 } 10230 10231 if (!ast_strlen_zero(iterator->username) && !s) 10232 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 10233 else 10234 ast_copy_string(name, iterator->name, sizeof(name)); 10235 10236 pstatus = peer_status(iterator, status, sizeof(status)); 10237 if (pstatus == 1) 10238 peers_mon_online++; 10239 else if (pstatus == 0) 10240 peers_mon_offline++; 10241 else { 10242 if (iterator->addr.sin_port == 0) 10243 peers_unmon_offline++; 10244 else 10245 peers_unmon_online++; 10246 } 10247 10248 snprintf(srch, sizeof(srch), FORMAT, name, 10249 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10250 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10251 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10252 iterator->ha ? " A " : " ", /* permit/deny */ 10253 ntohs(iterator->addr.sin_port), status, 10254 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10255 10256 if (!s) {/* Normal CLI list */ 10257 ast_cli(fd, FORMAT, name, 10258 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10259 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10260 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10261 iterator->ha ? " A " : " ", /* permit/deny */ 10262 10263 ntohs(iterator->addr.sin_port), status, 10264 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10265 } else { /* Manager format */ 10266 /* The names here need to be the same as other channels */ 10267 astman_append(s, 10268 "Event: PeerEntry\r\n%s" 10269 "Channeltype: SIP\r\n" 10270 "ObjectName: %s\r\n" 10271 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 10272 "IPaddress: %s\r\n" 10273 "IPport: %d\r\n" 10274 "Dynamic: %s\r\n" 10275 "Natsupport: %s\r\n" 10276 "VideoSupport: %s\r\n" 10277 "ACL: %s\r\n" 10278 "Status: %s\r\n" 10279 "RealtimeDevice: %s\r\n\r\n", 10280 idtext, 10281 iterator->name, 10282 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 10283 ntohs(iterator->addr.sin_port), 10284 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 10285 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 10286 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 10287 iterator->ha ? "yes" : "no", /* permit/deny */ 10288 status, 10289 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 10290 } 10291 10292 ASTOBJ_UNLOCK(iterator); 10293 10294 total_peers++; 10295 } while(0) ); 10296 10297 if (!s) 10298 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 10299 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 10300 10301 if (havepattern) 10302 regfree(®exbuf); 10303 10304 if (total) 10305 *total = total_peers; 10306 10307 10308 return RESULT_SUCCESS; 10309 #undef FORMAT 10310 #undef FORMAT2 10311 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 15294 of file chan_sip.c.
References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), ast_rtp_get_quality(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), LOG_ERROR, parse(), sip_pvt::rtp, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, type, and sip_pvt::vrtp.
15295 { 15296 struct ast_rtp_quality qos; 15297 struct sip_pvt *p = chan->tech_pvt; 15298 char *all = "", *parse = ast_strdupa(preparse); 15299 AST_DECLARE_APP_ARGS(args, 15300 AST_APP_ARG(param); 15301 AST_APP_ARG(type); 15302 AST_APP_ARG(field); 15303 ); 15304 AST_STANDARD_APP_ARGS(args, parse); 15305 15306 /* Sanity check */ 15307 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 15308 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 15309 return 0; 15310 } 15311 15312 if (strcasecmp(args.param, "rtpqos")) 15313 return 0; 15314 15315 /* Default arguments of audio,all */ 15316 if (ast_strlen_zero(args.type)) 15317 args.type = "audio"; 15318 if (ast_strlen_zero(args.field)) 15319 args.field = "all"; 15320 15321 memset(buf, 0, buflen); 15322 memset(&qos, 0, sizeof(qos)); 15323 15324 if (strcasecmp(args.type, "AUDIO") == 0) { 15325 all = ast_rtp_get_quality(p->rtp, &qos); 15326 } else if (strcasecmp(args.type, "VIDEO") == 0) { 15327 all = ast_rtp_get_quality(p->vrtp, &qos); 15328 } 15329 15330 if (strcasecmp(args.field, "local_ssrc") == 0) 15331 snprintf(buf, buflen, "%u", qos.local_ssrc); 15332 else if (strcasecmp(args.field, "local_lostpackets") == 0) 15333 snprintf(buf, buflen, "%u", qos.local_lostpackets); 15334 else if (strcasecmp(args.field, "local_jitter") == 0) 15335 snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0); 15336 else if (strcasecmp(args.field, "local_count") == 0) 15337 snprintf(buf, buflen, "%u", qos.local_count); 15338 else if (strcasecmp(args.field, "remote_ssrc") == 0) 15339 snprintf(buf, buflen, "%u", qos.remote_ssrc); 15340 else if (strcasecmp(args.field, "remote_lostpackets") == 0) 15341 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 15342 else if (strcasecmp(args.field, "remote_jitter") == 0) 15343 snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0); 15344 else if (strcasecmp(args.field, "remote_count") == 0) 15345 snprintf(buf, buflen, "%u", qos.remote_count); 15346 else if (strcasecmp(args.field, "rtt") == 0) 15347 snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0); 15348 else if (strcasecmp(args.field, "all") == 0) 15349 ast_copy_string(buf, all, buflen); 15350 else { 15351 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 15352 return -1; 15353 } 15354 return 0; 15355 }
static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 2292 of file chan_sip.c.
References sip_request::data, sip_request::len, and sip_request::lines.
Referenced by send_request(), and send_response().
02293 { 02294 if (!req->lines) { 02295 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 02296 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 02297 req->len += strlen(req->data + req->len); 02298 } 02299 }
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 6396 of file chan_sip.c.
References ast_build_string(), ast_codec_pref_getsize(), AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_ILBC, ast_getformatname(), ast_rtp_codec_getpref(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), AST_RTP_OPT_G726_NONSTANDARD, ast_test_flag, ast_verbose(), ast_format_list::cur_ms, sip_pvt::flags, sip_pvt::rtp, and SIP_G726_NONSTANDARD.
Referenced by add_sdp().
06399 { 06400 int rtp_code; 06401 struct ast_format_list fmt; 06402 06403 06404 if (debug) 06405 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 06406 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 06407 return; 06408 06409 if (p->rtp) { 06410 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 06411 fmt = ast_codec_pref_getsize(pref, codec); 06412 } 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 */ 06413 return; 06414 ast_build_string(m_buf, m_size, " %d", rtp_code); 06415 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06416 ast_rtp_lookup_mime_subtype(1, codec, 06417 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 06418 sample_rate); 06419 if (codec == AST_FORMAT_G729A) { 06420 /* Indicate that we don't support VAD (G.729 annex B) */ 06421 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 06422 } else if (codec == AST_FORMAT_G723_1) { 06423 /* Indicate that we don't support VAD (G.723.1 annex A) */ 06424 ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code); 06425 } else if (codec == AST_FORMAT_ILBC) { 06426 /* Add information about us using only 20/30 ms packetization */ 06427 ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 06428 } 06429 06430 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 06431 *min_packet_size = fmt.cur_ms; 06432 06433 /* Our first codec packetization processed cannot be less than zero */ 06434 if ((*min_packet_size) == 0 && fmt.cur_ms) 06435 *min_packet_size = fmt.cur_ms; 06436 }
static int add_digit | ( | struct sip_request * | req, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Add DTMF INFO tone to sip message.
Definition at line 6364 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_digit().
06365 { 06366 char tmp[256]; 06367 06368 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 06369 add_header(req, "Content-Type", "application/dtmf-relay"); 06370 add_header_contentLength(req, strlen(tmp)); 06371 add_line(req, tmp); 06372 return 0; 06373 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 5755 of file chan_sip.c.
References ast_log(), sip_request::data, find_alias(), sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, and SIP_MAX_HEADERS.
05756 { 05757 int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */ 05758 05759 if (req->headers == SIP_MAX_HEADERS) { 05760 ast_log(LOG_WARNING, "Out of SIP header space\n"); 05761 return -1; 05762 } 05763 05764 if (req->lines) { 05765 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 05766 return -1; 05767 } 05768 05769 if (maxlen <= 0) { 05770 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 05771 return -1; 05772 } 05773 05774 req->header[req->headers] = req->data + req->len; 05775 05776 if (compactheaders) 05777 var = find_alias(var, var); 05778 05779 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 05780 req->len += strlen(req->header[req->headers]); 05781 req->headers++; 05782 05783 return 0; 05784 }
static int add_header_contentLength | ( | struct sip_request * | req, | |
int | len | |||
) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 5787 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().
05788 { 05789 char clen[10]; 05790 05791 snprintf(clen, sizeof(clen), "%d", len); 05792 return add_header(req, "Content-Length", clen); 05793 }
static int add_line | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 5796 of file chan_sip.c.
References ast_log(), sip_request::data, sip_request::len, sip_request::line, sip_request::lines, and SIP_MAX_LINES.
05797 { 05798 if (req->lines == SIP_MAX_LINES) { 05799 ast_log(LOG_WARNING, "Out of SIP line space\n"); 05800 return -1; 05801 } 05802 if (!req->lines) { 05803 /* Add extra empty return */ 05804 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 05805 req->len += strlen(req->data + req->len); 05806 } 05807 if (req->len >= sizeof(req->data) - 4) { 05808 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 05809 return -1; 05810 } 05811 req->line[req->lines] = req->data + req->len; 05812 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 05813 req->len += strlen(req->line[req->lines]); 05814 req->lines++; 05815 return 0; 05816 }
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 6575 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().
06578 { 06579 int rtp_code; 06580 06581 if (debug) 06582 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 06583 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 06584 return; 06585 06586 ast_build_string(m_buf, m_size, " %d", rtp_code); 06587 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06588 ast_rtp_lookup_mime_subtype(0, format, 0), 06589 sample_rate); 06590 if (format == AST_RTP_DTMF) 06591 /* Indicate we support DTMF and FLASH... */ 06592 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 06593 }
static struct sip_auth * add_realm_authentication | ( | struct sip_auth * | authlist, | |
char * | configuration, | |||
int | lineno | |||
) | [static] |
Add realm authentication in list.
Definition at line 17070 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ast_log(), ast_strlen_zero(), ast_verbose(), LOG_DEBUG, sip_auth::md5secret, sip_auth::next, option_debug, option_verbose, sip_auth::realm, secret, and username.
Referenced by build_peer().
17071 { 17072 char authcopy[256]; 17073 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 17074 char *stringp; 17075 struct sip_auth *a, *b, *auth; 17076 17077 if (ast_strlen_zero(configuration)) 17078 return authlist; 17079 17080 if (option_debug) 17081 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 17082 17083 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 17084 stringp = authcopy; 17085 17086 username = stringp; 17087 realm = strrchr(stringp, '@'); 17088 if (realm) 17089 *realm++ = '\0'; 17090 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 17091 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 17092 return authlist; 17093 } 17094 stringp = username; 17095 username = strsep(&stringp, ":"); 17096 if (username) { 17097 secret = strsep(&stringp, ":"); 17098 if (!secret) { 17099 stringp = username; 17100 md5secret = strsep(&stringp,"#"); 17101 } 17102 } 17103 if (!(auth = ast_calloc(1, sizeof(*auth)))) 17104 return authlist; 17105 17106 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 17107 ast_copy_string(auth->username, username, sizeof(auth->username)); 17108 if (secret) 17109 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 17110 if (md5secret) 17111 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 17112 17113 /* find the end of the list */ 17114 for (b = NULL, a = authlist; a ; b = a, a = a->next) 17115 ; 17116 if (b) 17117 b->next = auth; /* Add structure add end of list */ 17118 else 17119 authlist = auth; 17120 17121 if (option_verbose > 2) 17122 ast_verbose("Added authentication for realm %s\n", realm); 17123 17124 return authlist; 17125 17126 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 5917 of file chan_sip.c.
References add_header(), ast_copy_string(), sip_route::hop, sip_route::next, and SIPBUFSIZE.
Referenced by reqprep().
05918 { 05919 char r[SIPBUFSIZE*2], *p; 05920 int n, rem = sizeof(r); 05921 05922 if (!route) 05923 return; 05924 05925 p = r; 05926 for (;route ; route = route->next) { 05927 n = strlen(route->hop); 05928 if (rem < n+3) /* we need room for ",<route>" */ 05929 break; 05930 if (p != r) { /* add a separator after fist route */ 05931 *p++ = ','; 05932 --rem; 05933 } 05934 *p++ = '<'; 05935 ast_copy_string(p, route->hop, rem); /* cannot fail */ 05936 p += n; 05937 *p++ = '>'; 05938 rem -= (n+2); 05939 } 05940 *p = '\0'; 05941 add_header(req, "Route", r); 05942 }
static enum sip_result add_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add Session Description Protocol message.
Definition at line 6603 of file chan_sip.c.
References add_codec_to_sdp(), add_header(), add_header_contentLength(), add_line(), add_noncodec_to_sdp(), ast_build_string(), ast_codec_pref_index(), AST_FAILURE, AST_FORMAT_AUDIO_MASK, AST_FORMAT_MAX_AUDIO, AST_FORMAT_MAX_VIDEO, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_inet_ntoa(), ast_internal_timing_enabled(), ast_log(), ast_rtp_get_us(), AST_RTP_MAX, AST_SUCCESS, ast_test_flag, ast_verbose(), capability, debug, FALSE, sip_pvt::flags, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len(), LOG_DEBUG, sip_pvt::maxcallbitrate, option_debug, sip_pvt::ourip, sip_pvt::owner, sip_pvt::prefcodec, sip_pvt::prefs, sip_pvt::redirip, sip_pvt::rtp, SDP_SAMPLE_RATE, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, SIP_PAGE2_T38SUPPORT_RTP, SIPBUFSIZE, sip_pvt::t38, t38properties::t38support, TRUE, sip_pvt::vredirip, and sip_pvt::vrtp.
06604 { 06605 int len = 0; 06606 int alreadysent = 0; 06607 06608 struct sockaddr_in sin; 06609 struct sockaddr_in vsin; 06610 struct sockaddr_in dest; 06611 struct sockaddr_in vdest = { 0, }; 06612 06613 /* SDP fields */ 06614 char *version = "v=0\r\n"; /* Protocol version */ 06615 char *subject = "s=session\r\n"; /* Subject of the session */ 06616 char owner[256]; /* Session owner/creator */ 06617 char connection[256]; /* Connection data */ 06618 char *stime = "t=0 0\r\n"; /* Time the session is active */ 06619 char bandwidth[256] = ""; /* Max bitrate */ 06620 char *hold; 06621 char m_audio[256]; /* Media declaration line for audio */ 06622 char m_video[256]; /* Media declaration line for video */ 06623 char a_audio[1024]; /* Attributes for audio */ 06624 char a_video[1024]; /* Attributes for video */ 06625 char *m_audio_next = m_audio; 06626 char *m_video_next = m_video; 06627 size_t m_audio_left = sizeof(m_audio); 06628 size_t m_video_left = sizeof(m_video); 06629 char *a_audio_next = a_audio; 06630 char *a_video_next = a_video; 06631 size_t a_audio_left = sizeof(a_audio); 06632 size_t a_video_left = sizeof(a_video); 06633 06634 int x; 06635 int capability; 06636 int needvideo = FALSE; 06637 int debug = sip_debug_test_pvt(p); 06638 int min_audio_packet_size = 0; 06639 int min_video_packet_size = 0; 06640 06641 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 06642 06643 if (!p->rtp) { 06644 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 06645 return AST_FAILURE; 06646 } 06647 06648 /* Set RTP Session ID and version */ 06649 if (!p->sessionid) { 06650 p->sessionid = getpid(); 06651 p->sessionversion = p->sessionid; 06652 } else 06653 p->sessionversion++; 06654 06655 /* Get our addresses */ 06656 ast_rtp_get_us(p->rtp, &sin); 06657 if (p->vrtp) 06658 ast_rtp_get_us(p->vrtp, &vsin); 06659 06660 /* Is this a re-invite to move the media out, then use the original offer from caller */ 06661 if (p->redirip.sin_addr.s_addr) { 06662 dest.sin_port = p->redirip.sin_port; 06663 dest.sin_addr = p->redirip.sin_addr; 06664 } else { 06665 dest.sin_addr = p->ourip; 06666 dest.sin_port = sin.sin_port; 06667 } 06668 06669 capability = p->jointcapability; 06670 06671 06672 if (option_debug > 1) { 06673 char codecbuf[SIPBUFSIZE]; 06674 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"); 06675 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 06676 } 06677 06678 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 06679 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 06680 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 06681 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 06682 } 06683 #endif 06684 06685 /* Check if we need video in this call */ 06686 if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 06687 if (p->vrtp) { 06688 needvideo = TRUE; 06689 if (option_debug > 1) 06690 ast_log(LOG_DEBUG, "This call needs video offers!\n"); 06691 } else if (option_debug > 1) 06692 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n"); 06693 } 06694 06695 06696 /* Ok, we need video. Let's add what we need for video and set codecs. 06697 Video is handled differently than audio since we can not transcode. */ 06698 if (needvideo) { 06699 /* Determine video destination */ 06700 if (p->vredirip.sin_addr.s_addr) { 06701 vdest.sin_addr = p->vredirip.sin_addr; 06702 vdest.sin_port = p->vredirip.sin_port; 06703 } else { 06704 vdest.sin_addr = p->ourip; 06705 vdest.sin_port = vsin.sin_port; 06706 } 06707 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 06708 06709 /* Build max bitrate string */ 06710 if (p->maxcallbitrate) 06711 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 06712 if (debug) 06713 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 06714 } 06715 06716 if (debug) 06717 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 06718 06719 /* Start building generic SDP headers */ 06720 06721 /* We break with the "recommendation" and send our IP, in order that our 06722 peer doesn't have to ast_gethostbyname() us */ 06723 06724 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 06725 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 06726 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 06727 06728 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) 06729 hold = "a=recvonly\r\n"; 06730 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) 06731 hold = "a=inactive\r\n"; 06732 else 06733 hold = "a=sendrecv\r\n"; 06734 06735 /* Now, start adding audio codecs. These are added in this order: 06736 - First what was requested by the calling channel 06737 - Then preferences in order from sip.conf device config for this peer/user 06738 - Then other codecs in capabilities, including video 06739 */ 06740 06741 /* Prefer the audio codec we were requested to use, first, no matter what 06742 Note that p->prefcodec can include video codecs, so mask them out 06743 */ 06744 if (capability & p->prefcodec) { 06745 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 06746 06747 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06748 &m_audio_next, &m_audio_left, 06749 &a_audio_next, &a_audio_left, 06750 debug, &min_audio_packet_size); 06751 alreadysent |= codec; 06752 } 06753 06754 /* Start by sending our preferred audio codecs */ 06755 for (x = 0; x < 32; x++) { 06756 int codec; 06757 06758 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 06759 break; 06760 06761 if (!(capability & codec)) 06762 continue; 06763 06764 if (alreadysent & codec) 06765 continue; 06766 06767 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06768 &m_audio_next, &m_audio_left, 06769 &a_audio_next, &a_audio_left, 06770 debug, &min_audio_packet_size); 06771 alreadysent |= codec; 06772 } 06773 06774 /* Now send any other common audio and video codecs, and non-codec formats: */ 06775 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 06776 if (!(capability & x)) /* Codec not requested */ 06777 continue; 06778 06779 if (alreadysent & x) /* Already added to SDP */ 06780 continue; 06781 06782 if (x <= AST_FORMAT_MAX_AUDIO) 06783 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 06784 &m_audio_next, &m_audio_left, 06785 &a_audio_next, &a_audio_left, 06786 debug, &min_audio_packet_size); 06787 else 06788 add_codec_to_sdp(p, x, 90000, 06789 &m_video_next, &m_video_left, 06790 &a_video_next, &a_video_left, 06791 debug, &min_video_packet_size); 06792 } 06793 06794 /* Now add DTMF RFC2833 telephony-event as a codec */ 06795 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 06796 if (!(p->jointnoncodeccapability & x)) 06797 continue; 06798 06799 add_noncodec_to_sdp(p, x, 8000, 06800 &m_audio_next, &m_audio_left, 06801 &a_audio_next, &a_audio_left, 06802 debug); 06803 } 06804 06805 if (option_debug > 2) 06806 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 06807 06808 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 06809 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 06810 06811 if (min_audio_packet_size) 06812 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 06813 06814 if (min_video_packet_size) 06815 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 06816 06817 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 06818 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 06819 06820 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 06821 if (needvideo) 06822 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 06823 06824 len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold); 06825 if (needvideo) /* only if video response is appropriate */ 06826 len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold); 06827 06828 add_header(resp, "Content-Type", "application/sdp"); 06829 add_header_contentLength(resp, len); 06830 add_line(resp, version); 06831 add_line(resp, owner); 06832 add_line(resp, subject); 06833 add_line(resp, connection); 06834 if (needvideo) /* only if video response is appropriate */ 06835 add_line(resp, bandwidth); 06836 add_line(resp, stime); 06837 add_line(resp, m_audio); 06838 add_line(resp, a_audio); 06839 add_line(resp, hold); 06840 if (needvideo) { /* only if video response is appropriate */ 06841 add_line(resp, m_video); 06842 add_line(resp, a_video); 06843 add_line(resp, hold); /* Repeat hold for the video stream */ 06844 } 06845 06846 /* Update lastrtprx when we send our SDP */ 06847 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 06848 06849 if (option_debug > 2) { 06850 char buf[SIPBUFSIZE]; 06851 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability)); 06852 } 06853 06854 return AST_SUCCESS; 06855 }
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 17006 of file chan_sip.c.
References ast_calloc, ast_copy_string(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), domain::list, LOG_DEBUG, and sipdebug.
17007 { 17008 struct domain *d; 17009 17010 if (ast_strlen_zero(domain)) { 17011 ast_log(LOG_WARNING, "Zero length domain.\n"); 17012 return 1; 17013 } 17014 17015 if (!(d = ast_calloc(1, sizeof(*d)))) 17016 return 0; 17017 17018 ast_copy_string(d->domain, domain, sizeof(d->domain)); 17019 17020 if (!ast_strlen_zero(context)) 17021 ast_copy_string(d->context, context, sizeof(d->context)); 17022 17023 d->mode = mode; 17024 17025 AST_LIST_LOCK(&domain_list); 17026 AST_LIST_INSERT_TAIL(&domain_list, d, list); 17027 AST_LIST_UNLOCK(&domain_list); 17028 17029 if (sipdebug) 17030 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 17031 17032 return 1; 17033 }
static int add_t38_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add T.38 Session Description Protocol message.
Definition at line 6475 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_udptl_get_local_max_datagram(), ast_udptl_get_us(), t38properties::capability, debug, t38properties::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len(), LOG_DEBUG, sip_pvt::ourip, t38properties::peercapability, s, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), t, sip_pvt::t38, t38_get_rate(), T38FAX_FILL_BIT_REMOVAL, T38FAX_RATE_MANAGEMENT_LOCAL_TCF, T38FAX_TRANSCODING_JBIG, T38FAX_TRANSCODING_MMR, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, T38FAX_VERSION, T38FAX_VERSION_0, T38FAX_VERSION_1, sip_pvt::udptl, and sip_pvt::udptlredirip.
Referenced by transmit_invite(), transmit_reinvite_with_t38_sdp(), and transmit_response_with_t38_sdp().
06476 { 06477 int len = 0; 06478 int x = 0; 06479 struct sockaddr_in udptlsin; 06480 char v[256] = ""; 06481 char s[256] = ""; 06482 char o[256] = ""; 06483 char c[256] = ""; 06484 char t[256] = ""; 06485 char m_modem[256]; 06486 char a_modem[1024]; 06487 char *m_modem_next = m_modem; 06488 size_t m_modem_left = sizeof(m_modem); 06489 char *a_modem_next = a_modem; 06490 size_t a_modem_left = sizeof(a_modem); 06491 struct sockaddr_in udptldest = { 0, }; 06492 int debug; 06493 06494 debug = sip_debug_test_pvt(p); 06495 len = 0; 06496 if (!p->udptl) { 06497 ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n"); 06498 return -1; 06499 } 06500 06501 if (!p->sessionid) { 06502 p->sessionid = getpid(); 06503 p->sessionversion = p->sessionid; 06504 } else 06505 p->sessionversion++; 06506 06507 /* Our T.38 end is */ 06508 ast_udptl_get_us(p->udptl, &udptlsin); 06509 06510 /* Determine T.38 UDPTL destination */ 06511 if (p->udptlredirip.sin_addr.s_addr) { 06512 udptldest.sin_port = p->udptlredirip.sin_port; 06513 udptldest.sin_addr = p->udptlredirip.sin_addr; 06514 } else { 06515 udptldest.sin_addr = p->ourip; 06516 udptldest.sin_port = udptlsin.sin_port; 06517 } 06518 06519 if (debug) 06520 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 06521 06522 /* We break with the "recommendation" and send our IP, in order that our 06523 peer doesn't have to ast_gethostbyname() us */ 06524 06525 if (debug) { 06526 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 06527 p->t38.capability, 06528 p->t38.peercapability, 06529 p->t38.jointcapability); 06530 } 06531 snprintf(v, sizeof(v), "v=0\r\n"); 06532 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr)); 06533 snprintf(s, sizeof(s), "s=session\r\n"); 06534 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr)); 06535 snprintf(t, sizeof(t), "t=0 0\r\n"); 06536 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 06537 06538 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 06539 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 06540 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 06541 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 06542 if ((x = t38_get_rate(p->t38.jointcapability))) 06543 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 06544 if ((p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) == T38FAX_FILL_BIT_REMOVAL) 06545 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval\r\n"); 06546 if ((p->t38.jointcapability & T38FAX_TRANSCODING_MMR) == T38FAX_TRANSCODING_MMR) 06547 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR\r\n"); 06548 if ((p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) == T38FAX_TRANSCODING_JBIG) 06549 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG\r\n"); 06550 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 06551 x = ast_udptl_get_local_max_datagram(p->udptl); 06552 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 06553 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 06554 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 06555 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 06556 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem); 06557 add_header(resp, "Content-Type", "application/sdp"); 06558 add_header_contentLength(resp, len); 06559 add_line(resp, v); 06560 add_line(resp, o); 06561 add_line(resp, s); 06562 add_line(resp, c); 06563 add_line(resp, t); 06564 add_line(resp, m_modem); 06565 add_line(resp, a_modem); 06566 06567 /* Update lastrtprx when we send our SDP */ 06568 p->lastrtprx = p->lastrtptx = time(NULL); 06569 06570 return 0; 06571 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 6353 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_message_with_text().
06354 { 06355 /* XXX Convert \n's to \r\n's XXX */ 06356 add_header(req, "Content-Type", "text/plain"); 06357 add_header_contentLength(req, strlen(text)); 06358 add_line(req, text); 06359 return 0; 06360 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 6377 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_vidupdate().
06378 { 06379 const char *xml_is_a_huge_waste_of_space = 06380 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 06381 " <media_control>\r\n" 06382 " <vc_primitive>\r\n" 06383 " <to_encoder>\r\n" 06384 " <picture_fast_update>\r\n" 06385 " </picture_fast_update>\r\n" 06386 " </to_encoder>\r\n" 06387 " </vc_primitive>\r\n" 06388 " </media_control>\r\n"; 06389 add_header(req, "Content-Type", "application/media_control+xml"); 06390 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 06391 add_line(req, xml_is_a_huge_waste_of_space); 06392 return 0; 06393 }
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 6300 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().
06301 { 06302 char tmpdat[256]; 06303 struct tm tm; 06304 time_t t = time(NULL); 06305 06306 gmtime_r(&t, &tm); 06307 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 06308 add_header(req, "Date", tmpdat); 06309 }
static void append_history_full | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1912 of file chan_sip.c.
References append_history_va(), ast_test_flag, sip_pvt::flags, and SIP_NO_HISTORY.
01913 { 01914 va_list ap; 01915 01916 if (!p) 01917 return; 01918 01919 if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY) 01920 && !recordhistory && !dumphistory) { 01921 return; 01922 } 01923 01924 va_start(ap, fmt); 01925 append_history_va(p, fmt, ap); 01926 va_end(ap); 01927 01928 return; 01929 }
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 1885 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, free, sip_history::list, and MAX_HISTORY_ENTRIES.
Referenced by append_history_full().
01886 { 01887 char buf[80], *c = buf; /* max history length */ 01888 struct sip_history *hist; 01889 int l; 01890 01891 vsnprintf(buf, sizeof(buf), fmt, ap); 01892 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 01893 l = strlen(buf) + 1; 01894 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) 01895 return; 01896 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 01897 free(hist); 01898 return; 01899 } 01900 memcpy(hist->event, buf, l); 01901 if (p->history_entries == MAX_HISTORY_ENTRIES) { 01902 struct sip_history *oldest; 01903 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 01904 p->history_entries--; 01905 free(oldest); 01906 } 01907 AST_LIST_INSERT_TAIL(p->history, hist, list); 01908 p->history_entries++; 01909 }
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 13548 of file chan_sip.c.
References ast_channel::_state, ast_deactivate_generator(), AST_FLAG_MOH, ast_moh_stop(), AST_STATE_UP, and ast_test_flag.
Referenced by attempt_transfer(), and handle_invite_replaces().
13549 { 13550 if (chan && chan->_state == AST_STATE_UP) { 13551 if (ast_test_flag(chan, AST_FLAG_MOH)) 13552 ast_moh_stop(chan); 13553 else if (chan->generatordata) 13554 ast_deactivate_generator(chan); 13555 } 13556 }
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 1845 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().
01846 { 01847 struct sockaddr_in theirs, ours; 01848 01849 /* Get our local information */ 01850 ast_ouraddrfor(them, us); 01851 theirs.sin_addr = *them; 01852 ours.sin_addr = *us; 01853 01854 if (localaddr && externip.sin_addr.s_addr && 01855 (ast_apply_ha(localaddr, &theirs)) && 01856 (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) { 01857 if (externexpire && time(NULL) >= externexpire) { 01858 struct ast_hostent ahp; 01859 struct hostent *hp; 01860 01861 externexpire = time(NULL) + externrefresh; 01862 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01863 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01864 } else 01865 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01866 } 01867 *us = externip.sin_addr; 01868 if (option_debug) { 01869 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 01870 ast_inet_ntoa(*(struct in_addr *)&them->s_addr)); 01871 } 01872 } else if (bindaddr.sin_addr.s_addr) 01873 *us = bindaddr.sin_addr; 01874 return AST_SUCCESS; 01875 }
Attempt transfer of SIP call This fix for attended transfers on a local PBX.
Definition at line 13560 of file chan_sip.c.
References ast_channel::_state, ast_channel_masquerade(), ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_state2str(), sip_dual::chan1, sip_dual::chan2, LOG_DEBUG, LOG_NOTICE, ast_channel::name, and option_debug.
13561 { 13562 int res = 0; 13563 struct ast_channel *peera = NULL, 13564 *peerb = NULL, 13565 *peerc = NULL, 13566 *peerd = NULL; 13567 13568 13569 /* We will try to connect the transferee with the target and hangup 13570 all channels to the transferer */ 13571 if (option_debug > 3) { 13572 ast_log(LOG_DEBUG, "Sip transfer:--------------------\n"); 13573 if (transferer->chan1) 13574 ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 13575 else 13576 ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n"); 13577 if (target->chan1) 13578 ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 13579 else 13580 ast_log(LOG_DEBUG, "-- No target first channel ---\n"); 13581 if (transferer->chan2) 13582 ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 13583 else 13584 ast_log(LOG_DEBUG, "-- No bridged call to transferee\n"); 13585 if (target->chan2) 13586 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)"); 13587 else 13588 ast_log(LOG_DEBUG, "-- No target second channel ---\n"); 13589 ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n"); 13590 } 13591 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 13592 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 13593 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 13594 peerc = transferer->chan2; /* Asterisk to Transferee */ 13595 peerd = target->chan2; /* Asterisk to Target */ 13596 if (option_debug > 2) 13597 ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n"); 13598 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 13599 peera = target->chan1; /* Transferer to PBX -> target channel */ 13600 peerb = transferer->chan1; /* Transferer to IVR*/ 13601 peerc = target->chan2; /* Asterisk to Target */ 13602 peerd = transferer->chan2; /* Nothing */ 13603 if (option_debug > 2) 13604 ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n"); 13605 } 13606 13607 if (peera && peerb && peerc && (peerb != peerc)) { 13608 ast_quiet_chan(peera); /* Stop generators */ 13609 ast_quiet_chan(peerb); 13610 ast_quiet_chan(peerc); 13611 if (peerd) 13612 ast_quiet_chan(peerd); 13613 13614 if (option_debug > 3) 13615 ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 13616 if (ast_channel_masquerade(peerb, peerc)) { 13617 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 13618 res = -1; 13619 } else 13620 ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n"); 13621 return res; 13622 } else { 13623 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 13624 if (transferer->chan1) 13625 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 13626 if (target->chan1) 13627 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 13628 return -2; 13629 } 13630 return 0; 13631 }
static int auto_congest | ( | const void * | nothing | ) | [static] |
Scheduled congestion on a call.
Definition at line 2984 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, ast_channel::name, and sip_pvt::owner.
02985 { 02986 struct sip_pvt *p = (struct sip_pvt *)nothing; 02987 02988 ast_mutex_lock(&p->lock); 02989 p->initid = -1; 02990 if (p->owner) { 02991 /* XXX fails on possible deadlock */ 02992 if (!ast_channel_trylock(p->owner)) { 02993 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 02994 append_history(p, "Cong", "Auto-congesting (timer)"); 02995 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 02996 ast_channel_unlock(p->owner); 02997 } 02998 } 02999 ast_mutex_unlock(&p->lock); 03000 return 0; 03001 }
static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 4521 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, sip_pvt::callid, sip_pvt::fromdomain, generate_random_string(), sip_pvt::ourip, and S_OR.
Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), and sip_send_mwi_to_peer().
04522 { 04523 char buf[33]; 04524 04525 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip)); 04526 04527 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04528 04529 }
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 4532 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, sip_pvt::callid, generate_random_string(), and S_OR.
Referenced by transmit_register().
04533 { 04534 char buf[33]; 04535 04536 const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip)); 04537 04538 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04539 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 7026 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, ast_strlen_zero(), sip_pvt::exten, 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().
07027 { 07028 /* Construct Contact: header */ 07029 if (ourport != STANDARD_SIP_PORT) 07030 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); 07031 else 07032 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip)); 07033 }
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 17337 of file chan_sip.c.
References __set_address_from_contact(), sip_peer::accountcode, add_realm_authentication(), sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_copy_string(), ast_free_ha(), ast_get_group(), ast_get_ip(), ast_get_ip_or_srv(), ast_get_time_t(), ast_inet_ntoa(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), AST_SCHED_DEL, ast_set2_flag, ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), ast_variables_destroy(), ASTOBJ_CONTAINER_FIND_UNLINK_FULL, ASTOBJ_FLAG_MARKED, ASTOBJ_INIT, ASTOBJ_UNMARK, ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, clear_realm_authentication(), sip_peer::contactha, sip_peer::context, sip_peer::defaddr, DEFAULT_MAXMS, destroy_association(), sip_peer::expire, ast_flags::flags, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_contact_ha, global_flags, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, ast_variable::name, sip_peer::name, ast_variable::next, sip_peer::objflags, option_debug, peerl, sip_peer::pickupgroup, sip_peer::prefs, reg_source_db(), sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sched, sip_peer::secret, set_peer_defaults(), sip_destroy_peer(), SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_REALTIME, SIP_USEREQPHONE, sip_peer::sockfd, STANDARD_SIP_PORT, sip_peer::subscribecontext, sip_peer::tohost, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, sip_peer::username, ast_variable::value, and sip_peer::vmexten.
17338 { 17339 struct sip_peer *peer = NULL; 17340 struct ast_ha *oldha = NULL; 17341 int obproxyfound=0; 17342 int found=0; 17343 int firstpass=1; 17344 int format=0; /* Ama flags */ 17345 time_t regseconds = 0; 17346 char *varname = NULL, *varval = NULL; 17347 struct ast_variable *tmpvar = NULL; 17348 struct ast_flags peerflags[2] = {{(0)}}; 17349 struct ast_flags mask[2] = {{(0)}}; 17350 char fullcontact[sizeof(peer->fullcontact)] = ""; 17351 17352 if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 17353 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 17354 /* We also use a case-sensitive comparison (unlike find_peer) so 17355 that case changes made to the peer name will be properly handled 17356 during reload 17357 */ 17358 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 17359 17360 if (peer) { 17361 /* Already in the list, remove it and it will be added back (or FREE'd) */ 17362 found = 1; 17363 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 17364 firstpass = 0; 17365 } else { 17366 if (!(peer = ast_calloc(1, sizeof(*peer)))) 17367 return NULL; 17368 17369 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 17370 rpeerobjs++; 17371 else 17372 speerobjs++; 17373 ASTOBJ_INIT(peer); 17374 } 17375 /* Note that our peer HAS had its reference count incrased */ 17376 if (firstpass) { 17377 peer->lastmsgssent = -1; 17378 oldha = peer->ha; 17379 peer->ha = NULL; 17380 set_peer_defaults(peer); /* Set peer defaults */ 17381 } 17382 if (!found && name) 17383 ast_copy_string(peer->name, name, sizeof(peer->name)); 17384 17385 /* If we have channel variables, remove them (reload) */ 17386 if (peer->chanvars) { 17387 ast_variables_destroy(peer->chanvars); 17388 peer->chanvars = NULL; 17389 /* XXX should unregister ? */ 17390 } 17391 17392 /* If we have realm authentication information, remove them (reload) */ 17393 clear_realm_authentication(peer->auth); 17394 peer->auth = NULL; 17395 peer->sockfd = -1; 17396 17397 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 17398 if (handle_common_options(&peerflags[0], &mask[0], v)) 17399 continue; 17400 if (realtime && !strcasecmp(v->name, "regseconds")) { 17401 ast_get_time_t(v->value, ®seconds, 0, NULL); 17402 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 17403 inet_aton(v->value, &(peer->addr.sin_addr)); 17404 } else if (realtime && !strcasecmp(v->name, "name")) 17405 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 17406 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 17407 /* Reconstruct field, because realtime separates our value at the ';' */ 17408 if (!ast_strlen_zero(fullcontact)) { 17409 strncat(fullcontact, ";", sizeof(fullcontact) - strlen(fullcontact) - 1); 17410 strncat(fullcontact, v->value, sizeof(fullcontact) - strlen(fullcontact) - 1); 17411 } else { 17412 ast_copy_string(fullcontact, v->value, sizeof(fullcontact)); 17413 ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT); 17414 } 17415 } else if (!strcasecmp(v->name, "secret")) 17416 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 17417 else if (!strcasecmp(v->name, "md5secret")) 17418 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 17419 else if (!strcasecmp(v->name, "auth")) 17420 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 17421 else if (!strcasecmp(v->name, "callerid")) { 17422 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 17423 } else if (!strcasecmp(v->name, "fullname")) { 17424 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 17425 } else if (!strcasecmp(v->name, "cid_number")) { 17426 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 17427 } else if (!strcasecmp(v->name, "context")) { 17428 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 17429 } else if (!strcasecmp(v->name, "subscribecontext")) { 17430 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 17431 } else if (!strcasecmp(v->name, "fromdomain")) { 17432 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 17433 } else if (!strcasecmp(v->name, "usereqphone")) { 17434 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 17435 } else if (!strcasecmp(v->name, "fromuser")) { 17436 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 17437 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 17438 if (!strcasecmp(v->value, "dynamic")) { 17439 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 17440 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 17441 } else { 17442 /* They'll register with us */ 17443 if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 17444 /* Initialize stuff if this is a new peer, or if it used to be 17445 * non-dynamic before the reload. */ 17446 memset(&peer->addr.sin_addr, 0, 4); 17447 if (peer->addr.sin_port) { 17448 /* If we've already got a port, make it the default rather than absolute */ 17449 peer->defaddr.sin_port = peer->addr.sin_port; 17450 peer->addr.sin_port = 0; 17451 } 17452 } 17453 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 17454 } 17455 } else { 17456 /* Non-dynamic. Make sure we become that way if we're not */ 17457 if (!AST_SCHED_DEL(sched, peer->expire)) { 17458 struct sip_peer *peer_ptr = peer; 17459 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17460 } 17461 ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 17462 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 17463 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 17464 ASTOBJ_UNREF(peer, sip_destroy_peer); 17465 return NULL; 17466 } 17467 } 17468 if (!strcasecmp(v->name, "outboundproxy")) 17469 obproxyfound=1; 17470 else { 17471 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 17472 if (!peer->addr.sin_port) 17473 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 17474 } 17475 if (global_dynamic_exclude_static) { 17476 global_contact_ha = ast_append_ha("deny", (char *)ast_inet_ntoa(peer->addr.sin_addr), global_contact_ha); 17477 } 17478 } 17479 } else if (!strcasecmp(v->name, "defaultip")) { 17480 if (ast_get_ip(&peer->defaddr, v->value)) { 17481 ASTOBJ_UNREF(peer, sip_destroy_peer); 17482 return NULL; 17483 } 17484 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 17485 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 17486 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 17487 peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha); 17488 } else if (!strcasecmp(v->name, "port")) { 17489 if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) 17490 peer->defaddr.sin_port = htons(atoi(v->value)); 17491 else 17492 peer->addr.sin_port = htons(atoi(v->value)); 17493 } else if (!strcasecmp(v->name, "callingpres")) { 17494 peer->callingpres = ast_parse_caller_presentation(v->value); 17495 if (peer->callingpres == -1) 17496 peer->callingpres = atoi(v->value); 17497 } else if (!strcasecmp(v->name, "username")) { 17498 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 17499 } else if (!strcasecmp(v->name, "language")) { 17500 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 17501 } else if (!strcasecmp(v->name, "regexten")) { 17502 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 17503 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 17504 peer->call_limit = atoi(v->value); 17505 if (peer->call_limit < 0) 17506 peer->call_limit = 0; 17507 } else if (!strcasecmp(v->name, "amaflags")) { 17508 format = ast_cdr_amaflags2int(v->value); 17509 if (format < 0) { 17510 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 17511 } else { 17512 peer->amaflags = format; 17513 } 17514 } else if (!strcasecmp(v->name, "accountcode")) { 17515 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 17516 } else if (!strcasecmp(v->name, "mohinterpret") 17517 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17518 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 17519 } else if (!strcasecmp(v->name, "mohsuggest")) { 17520 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 17521 } else if (!strcasecmp(v->name, "mailbox")) { 17522 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 17523 } else if (!strcasecmp(v->name, "hasvoicemail")) { 17524 /* People expect that if 'hasvoicemail' is set, that the mailbox will 17525 * be also set, even if not explicitly specified. */ 17526 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 17527 ast_copy_string(peer->mailbox, name, sizeof(peer->mailbox)); 17528 } 17529 } else if (!strcasecmp(v->name, "subscribemwi")) { 17530 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 17531 } else if (!strcasecmp(v->name, "vmexten")) { 17532 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 17533 } else if (!strcasecmp(v->name, "callgroup")) { 17534 peer->callgroup = ast_get_group(v->value); 17535 } else if (!strcasecmp(v->name, "allowtransfer")) { 17536 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17537 } else if (!strcasecmp(v->name, "pickupgroup")) { 17538 peer->pickupgroup = ast_get_group(v->value); 17539 } else if (!strcasecmp(v->name, "allow")) { 17540 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 17541 } else if (!strcasecmp(v->name, "disallow")) { 17542 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 17543 } else if (!strcasecmp(v->name, "autoframing")) { 17544 peer->autoframing = ast_true(v->value); 17545 } else if (!strcasecmp(v->name, "rtptimeout")) { 17546 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 17547 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17548 peer->rtptimeout = global_rtptimeout; 17549 } 17550 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 17551 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 17552 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17553 peer->rtpholdtimeout = global_rtpholdtimeout; 17554 } 17555 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 17556 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 17557 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 17558 peer->rtpkeepalive = global_rtpkeepalive; 17559 } 17560 } else if (!strcasecmp(v->name, "setvar")) { 17561 /* Set peer channel variable */ 17562 varname = ast_strdupa(v->value); 17563 if ((varval = strchr(varname, '='))) { 17564 *varval++ = '\0'; 17565 if ((tmpvar = ast_variable_new(varname, varval))) { 17566 tmpvar->next = peer->chanvars; 17567 peer->chanvars = tmpvar; 17568 } 17569 } 17570 } else if (!strcasecmp(v->name, "qualify")) { 17571 if (!strcasecmp(v->value, "no")) { 17572 peer->maxms = 0; 17573 } else if (!strcasecmp(v->value, "yes")) { 17574 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 17575 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 17576 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); 17577 peer->maxms = 0; 17578 } 17579 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) { 17580 /* This would otherwise cause a network storm, where the 17581 * qualify response refreshes the peer from the database, 17582 * which in turn causes another qualify to be sent, ad 17583 * infinitum. */ 17584 ast_log(LOG_WARNING, "Qualify is incompatible with dynamic uncached realtime. Please either turn rtcachefriends on or turn qualify off on peer '%s'\n", peer->name); 17585 peer->maxms = 0; 17586 } 17587 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17588 peer->maxcallbitrate = atoi(v->value); 17589 if (peer->maxcallbitrate < 0) 17590 peer->maxcallbitrate = default_maxcallbitrate; 17591 } 17592 } 17593 if (!ast_strlen_zero(fullcontact)) { 17594 ast_copy_string(peer->fullcontact, fullcontact, sizeof(peer->fullcontact)); 17595 /* We have a hostname in the fullcontact, but if we don't have an 17596 * address listed on the entry (or if it's 'dynamic'), then we need to 17597 * parse the entry to obtain the IP address, so a dynamic host can be 17598 * contacted immediately after reload (as opposed to waiting for it to 17599 * register once again). */ 17600 __set_address_from_contact(fullcontact, &peer->addr); 17601 } 17602 17603 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) { 17604 time_t nowtime = time(NULL); 17605 17606 if ((nowtime - regseconds) > 0) { 17607 destroy_association(peer); 17608 memset(&peer->addr, 0, sizeof(peer->addr)); 17609 if (option_debug) 17610 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 17611 } 17612 } 17613 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 17614 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 17615 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 17616 global_allowsubscribe = TRUE; /* No global ban any more */ 17617 if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME)) 17618 reg_source_db(peer); 17619 ASTOBJ_UNMARK(peer); 17620 ast_free_ha(oldha); 17621 return peer; 17622 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 11828 of file chan_sip.c.
References append_history, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_md5_hash(), ast_random(), ast_strlen_zero(), authl, sip_pvt::authname, sip_pvt::callid, sip_pvt::domain, find_realm_authentication(), LOG_DEBUG, sip_auth::md5secret, sip_registry::md5secret, sip_pvt::nonce, sip_pvt::noncecount, sip_pvt::opaque, sip_registry::opaque, sip_pvt::peerauth, sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_pvt::qop, sip_pvt::realm, sip_pvt::sa, sip_auth::secret, secret, sip_methods, sipdebug, text, sip_pvt::uri, sip_auth::username, sip_pvt::username, and username.
Referenced by reply_digest(), transmit_register(), and transmit_request_with_auth().
11829 { 11830 char a1[256]; 11831 char a2[256]; 11832 char a1_hash[256]; 11833 char a2_hash[256]; 11834 char resp[256]; 11835 char resp_hash[256]; 11836 char uri[256]; 11837 char opaque[256] = ""; 11838 char cnonce[80]; 11839 const char *username; 11840 const char *secret; 11841 const char *md5secret; 11842 struct sip_auth *auth = NULL; /* Realm authentication */ 11843 11844 if (!ast_strlen_zero(p->domain)) 11845 ast_copy_string(uri, p->domain, sizeof(uri)); 11846 else if (!ast_strlen_zero(p->uri)) 11847 ast_copy_string(uri, p->uri, sizeof(uri)); 11848 else 11849 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr)); 11850 11851 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 11852 11853 /* Check if we have separate auth credentials */ 11854 if(!(auth = find_realm_authentication(p->peerauth, p->realm))) /* Start with peer list */ 11855 auth = find_realm_authentication(authl, p->realm); /* If not, global list */ 11856 11857 if (auth) { 11858 ast_log(LOG_DEBUG, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username); 11859 username = auth->username; 11860 secret = auth->secret; 11861 md5secret = auth->md5secret; 11862 if (sipdebug) 11863 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 11864 } else { 11865 /* No authentication, use peer or register= config */ 11866 username = p->authname; 11867 secret = p->peersecret; 11868 md5secret = p->peermd5secret; 11869 } 11870 if (ast_strlen_zero(username)) /* We have no authentication */ 11871 return -1; 11872 11873 /* Calculate SIP digest response */ 11874 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 11875 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 11876 if (!ast_strlen_zero(md5secret)) 11877 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 11878 else 11879 ast_md5_hash(a1_hash,a1); 11880 ast_md5_hash(a2_hash,a2); 11881 11882 p->noncecount++; 11883 if (!ast_strlen_zero(p->qop)) 11884 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 11885 else 11886 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 11887 ast_md5_hash(resp_hash, resp); 11888 11889 /* only include the opaque string if it's set */ 11890 if (!ast_strlen_zero(p->opaque)) { 11891 snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque); 11892 } 11893 11894 /* XXX We hard code our qop to "auth" for now. XXX */ 11895 if (!ast_strlen_zero(p->qop)) 11896 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s, qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, opaque, cnonce, p->noncecount); 11897 else 11898 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s", username, p->realm, uri, p->nonce, resp_hash, opaque); 11899 11900 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 11901 11902 return 0; 11903 }
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 8496 of file chan_sip.c.
References __get_header(), ast_copy_string(), ast_log(), ast_malloc, ast_strlen_zero(), free_old_route(), get_header(), sip_route::hop, len(), list_route(), LOG_DEBUG, sip_route::next, option_debug, sip_pvt::route, sip_pvt::route_persistant, and sip_debug_test_pvt().
Referenced by handle_request_invite(), and handle_response_invite().
08497 { 08498 struct sip_route *thishop, *head, *tail; 08499 int start = 0; 08500 int len; 08501 const char *rr, *contact, *c; 08502 08503 /* Once a persistant route is set, don't fool with it */ 08504 if (p->route && p->route_persistant) { 08505 if (option_debug) 08506 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 08507 return; 08508 } 08509 08510 if (p->route) { 08511 free_old_route(p->route); 08512 p->route = NULL; 08513 } 08514 08515 /* We only want to create the route set the first time this is called */ 08516 p->route_persistant = 1; 08517 08518 /* Build a tailq, then assign it to p->route when done. 08519 * If backwards, we add entries from the head so they end up 08520 * in reverse order. However, we do need to maintain a correct 08521 * tail pointer because the contact is always at the end. 08522 */ 08523 head = NULL; 08524 tail = head; 08525 /* 1st we pass through all the hops in any Record-Route headers */ 08526 for (;;) { 08527 /* Each Record-Route header */ 08528 rr = __get_header(req, "Record-Route", &start); 08529 if (*rr == '\0') 08530 break; 08531 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 08532 ++rr; 08533 len = strcspn(rr, ">") + 1; 08534 /* Make a struct route */ 08535 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08536 /* ast_calloc is not needed because all fields are initialized in this block */ 08537 ast_copy_string(thishop->hop, rr, len); 08538 if (option_debug > 1) 08539 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 08540 /* Link in */ 08541 if (backwards) { 08542 /* Link in at head so they end up in reverse order */ 08543 thishop->next = head; 08544 head = thishop; 08545 /* If this was the first then it'll be the tail */ 08546 if (!tail) 08547 tail = thishop; 08548 } else { 08549 thishop->next = NULL; 08550 /* Link in at the end */ 08551 if (tail) 08552 tail->next = thishop; 08553 else 08554 head = thishop; 08555 tail = thishop; 08556 } 08557 } 08558 } 08559 } 08560 08561 /* Only append the contact if we are dealing with a strict router */ 08562 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 08563 /* 2nd append the Contact: if there is one */ 08564 /* Can be multiple Contact headers, comma separated values - we just take the first */ 08565 contact = get_header(req, "Contact"); 08566 if (!ast_strlen_zero(contact)) { 08567 if (option_debug > 1) 08568 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 08569 /* Look for <: delimited address */ 08570 c = strchr(contact, '<'); 08571 if (c) { 08572 /* Take to > */ 08573 ++c; 08574 len = strcspn(c, ">") + 1; 08575 } else { 08576 /* No <> - just take the lot */ 08577 c = contact; 08578 len = strlen(contact) + 1; 08579 } 08580 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08581 /* ast_calloc is not needed because all fields are initialized in this block */ 08582 ast_copy_string(thishop->hop, c, len); 08583 thishop->next = NULL; 08584 /* Goes at the end */ 08585 if (tail) 08586 tail->next = thishop; 08587 else 08588 head = thishop; 08589 } 08590 } 08591 } 08592 08593 /* Store as new route */ 08594 p->route = head; 08595 08596 /* For debugging dump what we ended up with */ 08597 if (sip_debug_test_pvt(p)) 08598 list_route(p->route); 08599 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 7036 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED, AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, AST_PRES_RESTRICTION, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, FALSE, sip_pvt::fromdomain, sip_pvt::fromuser, sip_pvt::ourip, sip_pvt::owner, sip_pvt::rpid, sip_pvt::rpid_from, S_OR, sip_pvt::tag, and TRUE.
Referenced by initreqprep().
07037 { 07038 int send_pres_tags = TRUE; 07039 const char *privacy=NULL; 07040 const char *screen=NULL; 07041 char buf[256]; 07042 const char *clid = default_callerid; 07043 const char *clin = NULL; 07044 const char *fromdomain; 07045 07046 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 07047 return; 07048 07049 if (p->owner && p->owner->cid.cid_num) 07050 clid = p->owner->cid.cid_num; 07051 if (p->owner && p->owner->cid.cid_name) 07052 clin = p->owner->cid.cid_name; 07053 if (ast_strlen_zero(clin)) 07054 clin = clid; 07055 07056 switch (p->callingpres) { 07057 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 07058 privacy = "off"; 07059 screen = "no"; 07060 break; 07061 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 07062 privacy = "off"; 07063 screen = "yes"; 07064 break; 07065 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 07066 privacy = "off"; 07067 screen = "no"; 07068 break; 07069 case AST_PRES_ALLOWED_NETWORK_NUMBER: 07070 privacy = "off"; 07071 screen = "yes"; 07072 break; 07073 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 07074 privacy = "full"; 07075 screen = "no"; 07076 break; 07077 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 07078 privacy = "full"; 07079 screen = "yes"; 07080 break; 07081 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 07082 privacy = "full"; 07083 screen = "no"; 07084 break; 07085 case AST_PRES_PROHIB_NETWORK_NUMBER: 07086 privacy = "full"; 07087 screen = "yes"; 07088 break; 07089 case AST_PRES_NUMBER_NOT_AVAILABLE: 07090 send_pres_tags = FALSE; 07091 break; 07092 default: 07093 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 07094 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 07095 privacy = "full"; 07096 else 07097 privacy = "off"; 07098 screen = "no"; 07099 break; 07100 } 07101 07102 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 07103 07104 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 07105 if (send_pres_tags) 07106 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 07107 ast_string_field_set(p, rpid, buf); 07108 07109 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 07110 S_OR(p->fromuser, clid), 07111 fromdomain, p->tag); 07112 }
static struct sip_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static] |
Initiate a SIP user structure from configuration (configuration or realtime).
Definition at line 17157 of file chan_sip.c.
References ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_copy_flags, ast_copy_string(), ast_free_ha(), ast_get_group(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_strdupa, ast_test_flag, ast_true(), ast_variable_new(), ASTOBJ_INIT, default_prefs, ast_flags::flags, format, global_flags, handle_common_options(), ast_variable::lineno, ast_variable::name, ast_variable::next, SIP_FLAGS_TO_COPY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_FLAGS_TO_COPY, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, and ast_variable::value.
17158 { 17159 struct sip_user *user; 17160 int format; 17161 struct ast_ha *oldha = NULL; 17162 char *varname = NULL, *varval = NULL; 17163 struct ast_variable *tmpvar = NULL; 17164 struct ast_flags userflags[2] = {{(0)}}; 17165 struct ast_flags mask[2] = {{(0)}}; 17166 17167 17168 if (!(user = ast_calloc(1, sizeof(*user)))) 17169 return NULL; 17170 17171 suserobjs++; 17172 ASTOBJ_INIT(user); 17173 ast_copy_string(user->name, name, sizeof(user->name)); 17174 oldha = user->ha; 17175 user->ha = NULL; 17176 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 17177 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 17178 user->capability = global_capability; 17179 user->allowtransfer = global_allowtransfer; 17180 user->maxcallbitrate = default_maxcallbitrate; 17181 user->autoframing = global_autoframing; 17182 user->prefs = default_prefs; 17183 /* set default context */ 17184 strcpy(user->context, default_context); 17185 strcpy(user->language, default_language); 17186 strcpy(user->mohinterpret, default_mohinterpret); 17187 strcpy(user->mohsuggest, default_mohsuggest); 17188 /* First we walk through the v parameters list and then the alt parameters list */ 17189 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 17190 if (handle_common_options(&userflags[0], &mask[0], v)) 17191 continue; 17192 17193 if (!strcasecmp(v->name, "context")) { 17194 ast_copy_string(user->context, v->value, sizeof(user->context)); 17195 } else if (!strcasecmp(v->name, "subscribecontext")) { 17196 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 17197 } else if (!strcasecmp(v->name, "setvar")) { 17198 varname = ast_strdupa(v->value); 17199 if ((varval = strchr(varname,'='))) { 17200 *varval++ = '\0'; 17201 if ((tmpvar = ast_variable_new(varname, varval))) { 17202 tmpvar->next = user->chanvars; 17203 user->chanvars = tmpvar; 17204 } 17205 } 17206 } else if (!strcasecmp(v->name, "permit") || 17207 !strcasecmp(v->name, "deny")) { 17208 user->ha = ast_append_ha(v->name, v->value, user->ha); 17209 } else if (!strcasecmp(v->name, "allowtransfer")) { 17210 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17211 } else if (!strcasecmp(v->name, "secret")) { 17212 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 17213 } else if (!strcasecmp(v->name, "md5secret")) { 17214 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 17215 } else if (!strcasecmp(v->name, "callerid")) { 17216 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 17217 } else if (!strcasecmp(v->name, "fullname")) { 17218 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 17219 } else if (!strcasecmp(v->name, "cid_number")) { 17220 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 17221 } else if (!strcasecmp(v->name, "callgroup")) { 17222 user->callgroup = ast_get_group(v->value); 17223 } else if (!strcasecmp(v->name, "pickupgroup")) { 17224 user->pickupgroup = ast_get_group(v->value); 17225 } else if (!strcasecmp(v->name, "language")) { 17226 ast_copy_string(user->language, v->value, sizeof(user->language)); 17227 } else if (!strcasecmp(v->name, "mohinterpret") 17228 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17229 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 17230 } else if (!strcasecmp(v->name, "mohsuggest")) { 17231 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 17232 } else if (!strcasecmp(v->name, "accountcode")) { 17233 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 17234 } else if (!strcasecmp(v->name, "call-limit")) { 17235 user->call_limit = atoi(v->value); 17236 if (user->call_limit < 0) 17237 user->call_limit = 0; 17238 } else if (!strcasecmp(v->name, "amaflags")) { 17239 format = ast_cdr_amaflags2int(v->value); 17240 if (format < 0) { 17241 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 17242 } else { 17243 user->amaflags = format; 17244 } 17245 } else if (!strcasecmp(v->name, "allow")) { 17246 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 17247 } else if (!strcasecmp(v->name, "disallow")) { 17248 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 17249 } else if (!strcasecmp(v->name, "autoframing")) { 17250 user->autoframing = ast_true(v->value); 17251 } else if (!strcasecmp(v->name, "callingpres")) { 17252 user->callingpres = ast_parse_caller_presentation(v->value); 17253 if (user->callingpres == -1) 17254 user->callingpres = atoi(v->value); 17255 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17256 user->maxcallbitrate = atoi(v->value); 17257 if (user->maxcallbitrate < 0) 17258 user->maxcallbitrate = default_maxcallbitrate; 17259 } 17260 /* We can't just report unknown options here because this may be a 17261 * type=friend entry. All user options are valid for a peer, but not 17262 * the other way around. */ 17263 } 17264 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 17265 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 17266 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 17267 global_allowsubscribe = TRUE; /* No global ban any more */ 17268 ast_free_ha(oldha); 17269 return user; 17270 }
static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 1828 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, ast_test_flag, sip_pvt::branch, sip_pvt::flags, sip_pvt::ourip, ourport, SIP_NAT, SIP_NAT_RFC3581, and SIP_PAGE2_TCP.
Referenced by reqprep(), sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_invite(), transmit_register(), and transmit_response_using_temp().
01829 { 01830 /* Work around buggy UNIDEN UIP200 firmware */ 01831 const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : ""; 01832 01833 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01834 ast_string_field_build(p, via, "SIP/2.0/%s %s:%d;branch=z9hG4bK%08x%s", 01835 ast_test_flag(&p->flags[1], SIP_PAGE2_TCP) ? "TCP" : "UDP", ast_inet_ntoa(p->ourip), ourport, p->branch, rport); 01836 01837 }
static int cb_extensionstate | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 8804 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_verbose(), sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, sip_pvt::laststate, sip_pvt::lock, NONE, option_verbose, sip_pvt::pendinginvite, sip_cancel_destroy(), SIP_PAGE2_STATECHANGEQUEUE, sip_scheddestroy(), sip_pvt::stateid, sip_pvt::subscribed, transmit_state_notify(), sip_pvt::username, VERBOSE_PREFIX_1, and VERBOSE_PREFIX_2.
Referenced by handle_request_subscribe(), and handle_response().
08805 { 08806 struct sip_pvt *p = data; 08807 08808 ast_mutex_lock(&p->lock); 08809 08810 switch(state) { 08811 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 08812 case AST_EXTENSION_REMOVED: /* Extension is gone */ 08813 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 08814 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08815 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 08816 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); 08817 p->stateid = -1; 08818 p->subscribed = NONE; 08819 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 08820 break; 08821 default: /* Tell user */ 08822 p->laststate = state; 08823 break; 08824 } 08825 if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */ 08826 if (!p->pendinginvite) { 08827 transmit_state_notify(p, state, 1, FALSE); 08828 } else { 08829 /* We already have a NOTIFY sent that is not answered. Queue the state up. 08830 if many state changes happen meanwhile, we will only send a notification of the last one */ 08831 ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 08832 } 08833 } 08834 if (option_verbose > 1) 08835 ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s[%s] new state %s for Notify User %s %s\n", exten, context, ast_extension_state2str(state), p->username, 08836 ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : ""); 08837 08838 08839 ast_mutex_unlock(&p->lock); 08840 08841 return 0; 08842 }
static void change_hold_state | ( | struct sip_pvt * | dialog, | |
struct sip_request * | req, | |||
int | holdstate, | |||
int | sendonly | |||
) | [static] |
Change hold state for a call.
Definition at line 5106 of file chan_sip.c.
References append_history, ast_clear_flag, ast_set_flag, ast_test_flag, sip_request::data, EVENT_FLAG_CALL, sip_pvt::flags, manager_event(), SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_ACTIVE, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, and sip_peer_hold().
Referenced by handle_request_invite(), and process_sdp().
05107 { 05108 if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 05109 sip_peer_hold(dialog, holdstate); 05110 if (global_callevents) 05111 manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold", 05112 "Channel: %s\r\n" 05113 "Uniqueid: %s\r\n", 05114 dialog->owner->name, 05115 dialog->owner->uniqueid); 05116 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data); 05117 if (!holdstate) { /* Put off remote hold */ 05118 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 05119 return; 05120 } 05121 /* No address for RTP, we're on hold */ 05122 05123 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 05124 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 05125 else if (sendonly == 2) /* Inactive stream */ 05126 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 05127 else 05128 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 05129 return; 05130 }
static enum check_auth_result check_auth | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
const char * | username, | |||
const char * | secret, | |||
const char * | md5secret, | |||
int | sipmethod, | |||
char * | uri, | |||
enum xmittype | reliable, | |||
int | ignore | |||
) | [static] |
Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).
XXX
XXX
Definition at line 8609 of file chan_sip.c.
References append_history, ast_copy_string(), ast_dynamic_str_thread_get(), ast_dynamic_str_thread_set(), AST_DYNSTR_BUILD_FAILED, ast_log(), ast_md5_hash(), ast_random(), ast_skip_blanks(), ast_string_field_build, ast_strlen_zero(), ast_test_flag, AUTH_CHALLENGE_SENT, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, AUTH_USERNAME_MISMATCH, check_auth_buf, CHECK_AUTH_BUF_INITLEN, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), keys, LOG_NOTICE, sip_pvt::randdata, s, S_OR, sip_methods, SIP_PKT_IGNORE, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, ast_dynamic_str::str, text, transmit_response_with_auth(), and TRUE.
Referenced by check_user_full(), and register_verify().
08612 { 08613 const char *response = "407 Proxy Authentication Required"; 08614 const char *reqheader = "Proxy-Authorization"; 08615 const char *respheader = "Proxy-Authenticate"; 08616 const char *authtoken; 08617 char a1_hash[256]; 08618 char resp_hash[256]=""; 08619 char *c; 08620 int wrongnonce = FALSE; 08621 int good_response; 08622 const char *usednonce = p->randdata; 08623 struct ast_dynamic_str *buf; 08624 int res; 08625 08626 /* table of recognised keywords, and their value in the digest */ 08627 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 08628 struct x { 08629 const char *key; 08630 const char *s; 08631 } *i, keys[] = { 08632 [K_RESP] = { "response=", "" }, 08633 [K_URI] = { "uri=", "" }, 08634 [K_USER] = { "username=", "" }, 08635 [K_NONCE] = { "nonce=", "" }, 08636 [K_LAST] = { NULL, NULL} 08637 }; 08638 08639 /* Always OK if no secret */ 08640 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 08641 return AUTH_SUCCESSFUL; 08642 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 08643 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 08644 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 08645 different circumstances! What a surprise. */ 08646 response = "401 Unauthorized"; 08647 reqheader = "Authorization"; 08648 respheader = "WWW-Authenticate"; 08649 } 08650 authtoken = get_header(req, reqheader); 08651 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 08652 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 08653 information */ 08654 if (!reliable) { 08655 /* Resend message if this was NOT a reliable delivery. Otherwise the 08656 retransmission should get it */ 08657 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08658 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 08659 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08660 } 08661 return AUTH_CHALLENGE_SENT; 08662 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 08663 /* We have no auth, so issue challenge and request authentication */ 08664 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08665 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08666 /* Schedule auto destroy in 32 seconds */ 08667 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08668 return AUTH_CHALLENGE_SENT; 08669 } 08670 08671 /* --- We have auth, so check it */ 08672 08673 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 08674 an example in the spec of just what it is you're doing a hash on. */ 08675 08676 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) 08677 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08678 08679 /* Make a copy of the response and parse it */ 08680 res = ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken); 08681 08682 if (res == AST_DYNSTR_BUILD_FAILED) 08683 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08684 08685 c = buf->str; 08686 08687 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 08688 for (i = keys; i->key != NULL; i++) { 08689 const char *separator = ","; /* default */ 08690 08691 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 08692 continue; 08693 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08694 c += strlen(i->key); 08695 if (*c == '"') { /* in quotes. Skip first and look for last */ 08696 c++; 08697 separator = "\""; 08698 } 08699 i->s = c; 08700 strsep(&c, separator); 08701 break; 08702 } 08703 if (i->key == NULL) /* not found, jump after space or comma */ 08704 strsep(&c, " ,"); 08705 } 08706 08707 /* Verify that digest username matches the username we auth as */ 08708 if (strcmp(username, keys[K_USER].s)) { 08709 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 08710 username, keys[K_USER].s); 08711 /* Oops, we're trying something here */ 08712 return AUTH_USERNAME_MISMATCH; 08713 } 08714 08715 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 08716 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */ 08717 wrongnonce = TRUE; 08718 usednonce = keys[K_NONCE].s; 08719 } 08720 08721 if (!ast_strlen_zero(md5secret)) 08722 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 08723 else { 08724 char a1[256]; 08725 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 08726 ast_md5_hash(a1_hash, a1); 08727 } 08728 08729 /* compute the expected response to compare with what we received */ 08730 { 08731 char a2[256]; 08732 char a2_hash[256]; 08733 char resp[256]; 08734 08735 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 08736 S_OR(keys[K_URI].s, uri)); 08737 ast_md5_hash(a2_hash, a2); 08738 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 08739 ast_md5_hash(resp_hash, resp); 08740 } 08741 08742 good_response = keys[K_RESP].s && 08743 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 08744 if (wrongnonce) { 08745 if (good_response) { 08746 if (sipdebug) 08747 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To")); 08748 /* We got working auth token, based on stale nonce . */ 08749 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08750 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 08751 } else { 08752 /* Everything was wrong, so give the device one more try with a new challenge */ 08753 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 08754 if (sipdebug) 08755 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 08756 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08757 } else { 08758 if (sipdebug) 08759 ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To")); 08760 } 08761 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 08762 } 08763 08764 /* Schedule auto destroy in 32 seconds */ 08765 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08766 return AUTH_CHALLENGE_SENT; 08767 } 08768 if (good_response) { 08769 append_history(p, "AuthOK", "Auth challenge succesful for %s", username); 08770 return AUTH_SUCCESSFUL; 08771 } 08772 08773 /* Ok, we have a bad username/secret pair */ 08774 /* Tell the UAS not to re-send this authentication data, because 08775 it will continue to fail 08776 */ 08777 08778 return AUTH_SECRET_FAILED; 08779 }
static void check_auth_buf_init | ( | void | ) | [static] |
static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 12302 of file chan_sip.c.
References ast_clear_flag, ast_log(), ast_test_flag, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, INV_CALLING, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, LOG_DEBUG, option_debug, sip_pvt::pendinginvite, SIP_BYE, SIP_CANCEL, SIP_NEEDREINVITE, SIP_PENDINGBYE, sip_scheddestroy(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), TRUE, sip_pvt::waitid, and XMIT_RELIABLE.
Referenced by handle_request(), and handle_response_invite().
12303 { 12304 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 12305 /* if we can't BYE, then this is really a pending CANCEL */ 12306 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) 12307 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 12308 /* Actually don't destroy us yet, wait for the 487 on our original 12309 INVITE, but do set an autodestruct just in case we never get it. */ 12310 else { 12311 /* We have a pending outbound invite, don't send someting 12312 new in-transaction */ 12313 if (p->pendinginvite) 12314 return; 12315 12316 /* Perhaps there is an SD change INVITE outstanding */ 12317 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 12318 } 12319 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 12320 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12321 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 12322 /* if we can't REINVITE, hold it for later */ 12323 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 12324 if (option_debug) 12325 ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 12326 } else { 12327 if (option_debug) 12328 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 12329 /* Didn't get to reinvite yet, so do it now */ 12330 transmit_reinvite_with_sdp(p); 12331 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 12332 } 12333 } 12334 }
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 17036 of file chan_sip.c.
References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, domain::domain, and domain::list.
Referenced by func_check_sipdomain(), get_destination(), handle_request_refer(), and register_verify().
17037 { 17038 struct domain *d; 17039 int result = 0; 17040 17041 AST_LIST_LOCK(&domain_list); 17042 AST_LIST_TRAVERSE(&domain_list, d, list) { 17043 if (strcasecmp(d->domain, domain)) 17044 continue; 17045 17046 if (len && !ast_strlen_zero(d->context)) 17047 ast_copy_string(context, d->context, len); 17048 17049 result = 1; 17050 break; 17051 } 17052 AST_LIST_UNLOCK(&domain_list); 17053 17054 return result; 17055 }
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 9922 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
09923 { 09924 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 09925 }
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 9598 of file chan_sip.c.
References sip_peer::accountcode, sip_user::accountcode, accountcode, sip_user::allowtransfer, sip_peer::amaflags, sip_user::amaflags, ast_apply_ha(), ast_copy_flags, ast_copy_string(), AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_is_shrinkable_phonenumber(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_variable_new(), ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, AUTH_FAKE_AUTH, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, sip_peer::autoframing, sip_user::autoframing, build_contact(), sip_peer::call_limit, sip_user::call_limit, sip_peer::callgroup, sip_user::callgroup, sip_peer::callingpres, sip_user::callingpres, sip_peer::capability, sip_user::capability, sip_peer::chanvars, sip_user::chanvars, check_auth(), sip_peer::cid_name, sip_user::cid_name, cid_name, sip_peer::cid_num, sip_user::cid_num, cid_num, sip_peer::context, context, sip_user::context, debug, do_setnat(), exten, find_peer(), find_user(), sip_peer::flags, sip_user::flags, sip_peer::fullcontact, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), sip_user::ha, sip_peer::language, sip_user::language, language, sip_peer::lastms, LOG_NOTICE, sip_peer::maxcallbitrate, sip_user::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_user::md5secret, sip_peer::mohinterpret, sip_user::mohinterpret, mohinterpret, sip_peer::mohsuggest, sip_user::mohsuggest, mohsuggest, sip_peer::name, sip_user::name, ast_variable::next, sip_peer::pickupgroup, sip_user::pickupgroup, sip_peer::prefs, sip_user::prefs, sip_peer::secret, sip_user::secret, SIP_CALL_LIMIT, sip_cancel_destroy(), sip_debug_test_addr(), sip_destroy_peer(), sip_destroy_user(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_INSECURE_INVITE, SIP_INVITE, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_VIDEOSUPPORT, SIP_PKT_IGNORE, SIP_SUBSCRIBE, SIP_TRUSTRPID, sip_peer::sipoptions, sip_user::sipoptions, sip_peer::subscribecontext, sip_user::subscribecontext, t, sip_peer::username, and username.
Referenced by check_user(), and handle_request_subscribe().
09601 { 09602 struct sip_user *user = NULL; 09603 struct sip_peer *peer; 09604 char from[256], *c; 09605 char *of; 09606 char rpid_num[50]; 09607 const char *rpid; 09608 enum check_auth_result res = AUTH_SUCCESSFUL; 09609 char *t; 09610 char calleridname[50]; 09611 int debug=sip_debug_test_addr(sin); 09612 struct ast_variable *tmpvar = NULL, *v = NULL; 09613 char *uri2 = ast_strdupa(uri); 09614 09615 /* Terminate URI */ 09616 t = uri2; 09617 while (*t && *t > 32 && *t != ';') 09618 t++; 09619 *t = '\0'; 09620 ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */ 09621 if (pedanticsipchecking) 09622 ast_uri_decode(from); 09623 /* XXX here tries to map the username for invite things */ 09624 memset(calleridname, 0, sizeof(calleridname)); 09625 get_calleridname(from, calleridname, sizeof(calleridname)); 09626 if (calleridname[0]) 09627 ast_string_field_set(p, cid_name, calleridname); 09628 09629 rpid = get_header(req, "Remote-Party-ID"); 09630 memset(rpid_num, 0, sizeof(rpid_num)); 09631 if (!ast_strlen_zero(rpid)) 09632 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 09633 09634 of = get_in_brackets(from); 09635 if (ast_strlen_zero(p->exten)) { 09636 t = uri2; 09637 if (!strncasecmp(t, "sip:", 4)) 09638 t+= 4; 09639 ast_string_field_set(p, exten, t); 09640 t = strchr(p->exten, '@'); 09641 if (t) 09642 *t = '\0'; 09643 if (ast_strlen_zero(p->our_contact)) 09644 build_contact(p); 09645 } 09646 /* save the URI part of the From header */ 09647 ast_string_field_set(p, from, of); 09648 if (strncasecmp(of, "sip:", 4)) { 09649 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 09650 } else 09651 of += 4; 09652 /* Get just the username part */ 09653 if ((c = strchr(of, '@'))) { 09654 char *tmp; 09655 *c = '\0'; 09656 if ((c = strchr(of, ':'))) 09657 *c = '\0'; 09658 tmp = ast_strdupa(of); 09659 /* We need to be able to handle auth-headers looking like 09660 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 09661 */ 09662 tmp = strsep(&tmp, ";"); 09663 if (ast_is_shrinkable_phonenumber(tmp)) 09664 ast_shrink_phone_number(tmp); 09665 ast_string_field_set(p, cid_num, tmp); 09666 } 09667 09668 if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */ 09669 user = find_user(of, 1); 09670 09671 /* Find user based on user name in the from header */ 09672 if (user && ast_apply_ha(user->ha, sin)) { 09673 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09674 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09675 if (sipmethod == SIP_INVITE) { 09676 /* copy channel vars */ 09677 for (v = user->chanvars ; v ; v = v->next) { 09678 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09679 tmpvar->next = p->chanvars; 09680 p->chanvars = tmpvar; 09681 } 09682 } 09683 } 09684 p->prefs = user->prefs; 09685 /* Set Frame packetization */ 09686 if (p->rtp) { 09687 ast_rtp_codec_setpref(p->rtp, &p->prefs); 09688 p->autoframing = user->autoframing; 09689 } 09690 /* replace callerid if rpid found, and not restricted */ 09691 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09692 char *tmp; 09693 if (*calleridname) 09694 ast_string_field_set(p, cid_name, calleridname); 09695 tmp = ast_strdupa(rpid_num); 09696 if (ast_is_shrinkable_phonenumber(tmp)) 09697 ast_shrink_phone_number(tmp); 09698 ast_string_field_set(p, cid_num, tmp); 09699 } 09700 09701 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 09702 09703 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09704 if (sip_cancel_destroy(p)) 09705 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09706 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09707 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09708 /* Copy SIP extensions profile from INVITE */ 09709 if (p->sipoptions) 09710 user->sipoptions = p->sipoptions; 09711 09712 /* If we have a call limit, set flag */ 09713 if (user->call_limit) 09714 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09715 if (!ast_strlen_zero(user->context)) 09716 ast_string_field_set(p, context, user->context); 09717 if (!ast_strlen_zero(user->cid_num)) { 09718 char *tmp = ast_strdupa(user->cid_num); 09719 if (ast_is_shrinkable_phonenumber(tmp)) 09720 ast_shrink_phone_number(tmp); 09721 ast_string_field_set(p, cid_num, tmp); 09722 } 09723 if (!ast_strlen_zero(user->cid_name)) 09724 ast_string_field_set(p, cid_name, user->cid_name); 09725 ast_string_field_set(p, username, user->name); 09726 ast_string_field_set(p, peername, user->name); 09727 ast_string_field_set(p, peersecret, user->secret); 09728 ast_string_field_set(p, peermd5secret, user->md5secret); 09729 ast_string_field_set(p, subscribecontext, user->subscribecontext); 09730 ast_string_field_set(p, accountcode, user->accountcode); 09731 ast_string_field_set(p, language, user->language); 09732 ast_string_field_set(p, mohsuggest, user->mohsuggest); 09733 ast_string_field_set(p, mohinterpret, user->mohinterpret); 09734 p->allowtransfer = user->allowtransfer; 09735 p->amaflags = user->amaflags; 09736 p->callgroup = user->callgroup; 09737 p->pickupgroup = user->pickupgroup; 09738 if (user->callingpres) /* User callingpres setting will override RPID header */ 09739 p->callingpres = user->callingpres; 09740 09741 /* Set default codec settings for this call */ 09742 p->capability = user->capability; /* User codec choice */ 09743 p->jointcapability = user->capability; /* Our codecs */ 09744 if (p->peercapability) /* AND with peer's codecs */ 09745 p->jointcapability &= p->peercapability; 09746 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09747 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09748 p->noncodeccapability |= AST_RTP_DTMF; 09749 else 09750 p->noncodeccapability &= ~AST_RTP_DTMF; 09751 p->jointnoncodeccapability = p->noncodeccapability; 09752 if (p->t38.peercapability) 09753 p->t38.jointcapability &= p->t38.peercapability; 09754 p->maxcallbitrate = user->maxcallbitrate; 09755 /* If we do not support video, remove video from call structure */ 09756 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09757 ast_rtp_destroy(p->vrtp); 09758 p->vrtp = NULL; 09759 } 09760 } 09761 if (user && debug) 09762 ast_verbose("Found user '%s'\n", user->name); 09763 } else { 09764 if (user) { 09765 if (!authpeer && debug) 09766 ast_verbose("Found user '%s', but fails host access\n", user->name); 09767 ASTOBJ_UNREF(user,sip_destroy_user); 09768 } 09769 user = NULL; 09770 } 09771 09772 if (!user) { 09773 /* If we didn't find a user match, check for peers */ 09774 if (sipmethod == SIP_SUBSCRIBE) 09775 /* For subscribes, match on peer name only */ 09776 peer = find_peer(of, NULL, 1, 0); 09777 else 09778 /* Look for peer based on the IP address we received data from */ 09779 /* If peer is registered from this IP address or have this as a default 09780 IP address, this call is from the peer 09781 */ 09782 peer = find_peer(NULL, &p->recv, 1, 0); 09783 09784 if (peer) { 09785 /* Set Frame packetization */ 09786 if (p->rtp) { 09787 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09788 p->autoframing = peer->autoframing; 09789 } 09790 if (debug) 09791 ast_verbose("Found peer '%s'\n", peer->name); 09792 09793 /* Take the peer */ 09794 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09795 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09796 09797 /* Copy SIP extensions profile to peer */ 09798 if (p->sipoptions) 09799 peer->sipoptions = p->sipoptions; 09800 09801 /* replace callerid if rpid found, and not restricted */ 09802 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09803 char *tmp = ast_strdupa(rpid_num); 09804 if (*calleridname) 09805 ast_string_field_set(p, cid_name, calleridname); 09806 if (ast_is_shrinkable_phonenumber(tmp)) 09807 ast_shrink_phone_number(tmp); 09808 ast_string_field_set(p, cid_num, tmp); 09809 } 09810 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 09811 09812 ast_string_field_set(p, peersecret, peer->secret); 09813 ast_string_field_set(p, peermd5secret, peer->md5secret); 09814 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 09815 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 09816 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 09817 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 09818 p->callingpres = peer->callingpres; 09819 if (peer->maxms && peer->lastms) 09820 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 09821 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 09822 /* Pretend there is no required authentication */ 09823 ast_string_field_free(p, peersecret); 09824 ast_string_field_free(p, peermd5secret); 09825 } 09826 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09827 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09828 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09829 /* If we have a call limit, set flag */ 09830 if (peer->call_limit) 09831 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09832 ast_string_field_set(p, peername, peer->name); 09833 ast_string_field_set(p, authname, peer->name); 09834 09835 if (sipmethod == SIP_INVITE) { 09836 /* copy channel vars */ 09837 for (v = peer->chanvars ; v ; v = v->next) { 09838 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09839 tmpvar->next = p->chanvars; 09840 p->chanvars = tmpvar; 09841 } 09842 } 09843 } 09844 if (authpeer) { 09845 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 09846 } 09847 09848 if (!ast_strlen_zero(peer->username)) { 09849 ast_string_field_set(p, username, peer->username); 09850 /* Use the default username for authentication on outbound calls */ 09851 /* XXX this takes the name from the caller... can we override ? */ 09852 ast_string_field_set(p, authname, peer->username); 09853 } 09854 if (!ast_strlen_zero(peer->cid_num)) { 09855 char *tmp = ast_strdupa(peer->cid_num); 09856 if (ast_is_shrinkable_phonenumber(tmp)) 09857 ast_shrink_phone_number(tmp); 09858 ast_string_field_set(p, cid_num, tmp); 09859 } 09860 if (!ast_strlen_zero(peer->cid_name)) 09861 ast_string_field_set(p, cid_name, peer->cid_name); 09862 ast_string_field_set(p, fullcontact, peer->fullcontact); 09863 if (!ast_strlen_zero(peer->context)) 09864 ast_string_field_set(p, context, peer->context); 09865 ast_string_field_set(p, peersecret, peer->secret); 09866 ast_string_field_set(p, peermd5secret, peer->md5secret); 09867 ast_string_field_set(p, language, peer->language); 09868 ast_string_field_set(p, accountcode, peer->accountcode); 09869 p->amaflags = peer->amaflags; 09870 p->callgroup = peer->callgroup; 09871 p->pickupgroup = peer->pickupgroup; 09872 p->capability = peer->capability; 09873 p->prefs = peer->prefs; 09874 p->jointcapability = peer->capability; 09875 if (p->peercapability) 09876 p->jointcapability &= p->peercapability; 09877 p->maxcallbitrate = peer->maxcallbitrate; 09878 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09879 ast_rtp_destroy(p->vrtp); 09880 p->vrtp = NULL; 09881 } 09882 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09883 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09884 p->noncodeccapability |= AST_RTP_DTMF; 09885 else 09886 p->noncodeccapability &= ~AST_RTP_DTMF; 09887 p->jointnoncodeccapability = p->noncodeccapability; 09888 if (p->t38.peercapability) 09889 p->t38.jointcapability &= p->t38.peercapability; 09890 } 09891 ASTOBJ_UNREF(peer, sip_destroy_peer); 09892 } else { 09893 if (debug) 09894 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 09895 09896 /* do we allow guests? */ 09897 if (!global_allowguest) { 09898 if (global_alwaysauthreject) 09899 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 09900 else 09901 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 09902 } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09903 char *tmp = ast_strdupa(rpid_num); 09904 if (*calleridname) 09905 ast_string_field_set(p, cid_name, calleridname); 09906 if (ast_is_shrinkable_phonenumber(tmp)) 09907 ast_shrink_phone_number(tmp); 09908 ast_string_field_set(p, cid_num, tmp); 09909 } 09910 } 09911 09912 } 09913 09914 if (user) 09915 ASTOBJ_UNREF(user, sip_destroy_user); 09916 return res; 09917 }
static void check_via | ( | struct sip_pvt * | p, | |
const struct sip_request * | req | |||
) | [static] |
check Via: header for hostname, port and rport request/answer
Definition at line 9466 of file chan_sip.c.
References ahp, ast_copy_string(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_skip_blanks(), ast_verbose(), sip_pvt::flags, get_header(), hp, sip_pvt::sa, sip_debug_test_pvt(), sip_nat_mode(), SIP_NAT_ROUTE, sip_real_dst(), and STANDARD_SIP_PORT.
Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_register(), handle_request_subscribe(), and transmit_response_using_temp().
09467 { 09468 char via[512]; 09469 char *c, *pt; 09470 struct hostent *hp; 09471 struct ast_hostent ahp; 09472 09473 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 09474 09475 /* Work on the leftmost value of the topmost Via header */ 09476 c = strchr(via, ','); 09477 if (c) 09478 *c = '\0'; 09479 09480 /* Check for rport */ 09481 c = strstr(via, ";rport"); 09482 if (c && (c[6] != '=')) /* rport query, not answer */ 09483 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 09484 09485 c = strchr(via, ';'); 09486 if (c) 09487 *c = '\0'; 09488 09489 c = strchr(via, ' '); 09490 if (c) { 09491 *c = '\0'; 09492 c = ast_skip_blanks(c+1); 09493 if ((strcasecmp(via, "SIP/2.0/UDP")) && (strcasecmp(via, "SIP/2.0/TCP"))) { 09494 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 09495 return; 09496 } 09497 pt = strchr(c, ':'); 09498 if (pt) 09499 *pt++ = '\0'; /* remember port pointer */ 09500 hp = ast_gethostbyname(c, &ahp); 09501 if (!hp) { 09502 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 09503 return; 09504 } 09505 memset(&p->sa, 0, sizeof(p->sa)); 09506 p->sa.sin_family = AF_INET; 09507 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 09508 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 09509 09510 if (sip_debug_test_pvt(p)) { 09511 const struct sockaddr_in *dst = sip_real_dst(p); 09512 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 09513 } 09514 } 09515 }
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 10366 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), ast_copy_string(), and AST_MAX_CONTEXT.
10367 { 10368 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 10369 10370 while ((oldcontext = strsep(&old, "&"))) { 10371 stalecontext = '\0'; 10372 ast_copy_string(newlist, new, sizeof(newlist)); 10373 stringp = newlist; 10374 while ((newcontext = strsep(&stringp, "&"))) { 10375 if (strcmp(newcontext, oldcontext) == 0) { 10376 /* This is not the context you're looking for */ 10377 stalecontext = '\0'; 10378 break; 10379 } else if (strcmp(newcontext, oldcontext)) { 10380 stalecontext = oldcontext; 10381 } 10382 10383 } 10384 if (stalecontext) 10385 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 10386 } 10387 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 17129 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().
17130 { 17131 struct sip_auth *a = authlist; 17132 struct sip_auth *b; 17133 17134 while (a) { 17135 b = a; 17136 a = a->next; 17137 free(b); 17138 } 17139 17140 return 1; 17141 }
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 17058 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free, and domain::list.
Referenced by reload_config(), and unload_module().
17059 { 17060 struct domain *d; 17061 17062 AST_LIST_LOCK(&domain_list); 17063 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 17064 free(d); 17065 AST_LIST_UNLOCK(&domain_list); 17066 }
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 11181 of file chan_sip.c.
References complete_sip_peer().
11182 { 11183 if (pos == 3) 11184 return complete_sip_peer(word, state, 0); 11185 11186 return NULL; 11187 }
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 11155 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, and peerl.
Referenced by complete_sip_debug_peer(), complete_sip_prune_realtime_peer(), complete_sip_show_peer(), and complete_sipnotify().
11156 { 11157 char *result = NULL; 11158 int wordlen = strlen(word); 11159 int which = 0; 11160 11161 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 11162 /* locking of the object is not required because only the name and flags are being compared */ 11163 if (!strncasecmp(word, iterator->name, wordlen) && 11164 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 11165 ++which > state) 11166 result = ast_strdup(iterator->name); 11167 } while(0) ); 11168 return result; 11169 }
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 11249 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
11250 { 11251 if (pos == 4) 11252 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11253 return NULL; 11254 }
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 11257 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
11258 { 11259 if (pos == 4) 11260 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11261 11262 return NULL; 11263 }
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 11172 of file chan_sip.c.
References complete_sip_peer().
11173 { 11174 if (pos == 3) 11175 return complete_sip_peer(word, state, 0); 11176 11177 return NULL; 11178 }
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 11210 of file chan_sip.c.
References complete_sip_user().
11211 { 11212 if (pos == 3) 11213 return complete_sip_user(word, state, 0); 11214 11215 return NULL; 11216 }
static char * complete_sip_user | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on user name.
Definition at line 11190 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, and userl.
Referenced by complete_sip_prune_realtime_user(), and complete_sip_show_user().
11191 { 11192 char *result = NULL; 11193 int wordlen = strlen(word); 11194 int which = 0; 11195 11196 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 11197 /* locking of the object is not required because only the name and flags are being compared */ 11198 if (!strncasecmp(word, iterator->name, wordlen)) { 11199 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 11200 continue; 11201 if (++which > state) { 11202 result = ast_strdup(iterator->name); 11203 } 11204 } 11205 } while(0) ); 11206 return result; 11207 }
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 11132 of file chan_sip.c.
References ast_mutex_lock(), ast_strdup, sip_pvt::callid, iflist, iflock, and sip_pvt::next.
11133 { 11134 int which=0; 11135 struct sip_pvt *cur; 11136 char *c = NULL; 11137 int wordlen = strlen(word); 11138 11139 if (pos != 3) { 11140 return NULL; 11141 } 11142 11143 ast_mutex_lock(&iflock); 11144 for (cur = iflist; cur; cur = cur->next) { 11145 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 11146 c = ast_strdup(cur->callid); 11147 break; 11148 } 11149 } 11150 ast_mutex_unlock(&iflock); 11151 return c; 11152 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 11219 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
11220 { 11221 char *c = NULL; 11222 11223 if (pos == 2) { 11224 int which = 0; 11225 char *cat = NULL; 11226 int wordlen = strlen(word); 11227 11228 /* do completion for notify type */ 11229 11230 if (!notify_types) 11231 return NULL; 11232 11233 while ( (cat = ast_category_browse(notify_types, cat)) ) { 11234 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 11235 c = ast_strdup(cat); 11236 break; 11237 } 11238 } 11239 return c; 11240 } 11241 11242 if (pos > 2) 11243 return complete_sip_peer(word, state, 0); 11244 11245 return NULL; 11246 }
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 5830 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
05831 { 05832 int start = 0; 05833 int copied = 0; 05834 for (;;) { 05835 const char *tmp = __get_header(orig, field, &start); 05836 05837 if (ast_strlen_zero(tmp)) 05838 break; 05839 /* Add what we're responding to */ 05840 add_header(req, field, tmp); 05841 copied++; 05842 } 05843 return copied ? 0 : -1; 05844 }
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 5819 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
05820 { 05821 const char *tmp = get_header(orig, field); 05822 05823 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 05824 return add_header(req, field, tmp); 05825 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 05826 return -1; 05827 }
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 6879 of file chan_sip.c.
References offset.
Referenced by handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), initialize_initreq(), queue_request(), sip_park(), and sip_park_thread().
06880 { 06881 long offset; 06882 int x; 06883 offset = ((void *)dst) - ((void *)src); 06884 /* First copy stuff */ 06885 memcpy(dst, src, sizeof(*dst)); 06886 /* Now fix pointer arithmetic */ 06887 for (x=0; x < src->headers; x++) 06888 dst->header[x] += offset; 06889 for (x=0; x < src->lines; x++) 06890 dst->line[x] += offset; 06891 dst->rlPart1 += offset; 06892 dst->rlPart2 += offset; 06893 }
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 5852 of file chan_sip.c.
References __get_header(), add_header(), ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_strlen_zero(), ast_test_flag, sip_pvt::flags, LOG_NOTICE, sip_pvt::recv, SIP_NAT, SIP_NAT_ALWAYS, and SIP_NAT_RFC3581.
Referenced by respprep().
05853 { 05854 int copied = 0; 05855 int start = 0; 05856 05857 for (;;) { 05858 char new[512]; 05859 const char *oh = __get_header(orig, field, &start); 05860 05861 if (ast_strlen_zero(oh)) 05862 break; 05863 05864 if (!copied) { /* Only check for empty rport in topmost via header */ 05865 char leftmost[512], *others, *rport; 05866 05867 /* Only work on leftmost value */ 05868 ast_copy_string(leftmost, oh, sizeof(leftmost)); 05869 others = strchr(leftmost, ','); 05870 if (others) 05871 *others++ = '\0'; 05872 05873 /* Find ;rport; (empty request) */ 05874 rport = strstr(leftmost, ";rport"); 05875 if (rport && *(rport+6) == '=') 05876 rport = NULL; /* We already have a parameter to rport */ 05877 05878 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 05879 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 05880 /* We need to add received port - rport */ 05881 char *end; 05882 05883 rport = strstr(leftmost, ";rport"); 05884 05885 if (rport) { 05886 end = strchr(rport + 1, ';'); 05887 if (end) 05888 memmove(rport, end, strlen(end) + 1); 05889 else 05890 *rport = '\0'; 05891 } 05892 05893 /* Add rport to first VIA header if requested */ 05894 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 05895 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05896 ntohs(p->recv.sin_port), 05897 others ? "," : "", others ? others : ""); 05898 } else { 05899 /* We should *always* add a received to the topmost via */ 05900 snprintf(new, sizeof(new), "%s;received=%s%s%s", 05901 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05902 others ? "," : "", others ? others : ""); 05903 } 05904 oh = new; /* the header to copy */ 05905 } /* else add the following via headers untouched */ 05906 add_header(req, field, oh); 05907 copied++; 05908 } 05909 if (!copied) { 05910 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 05911 return -1; 05912 } 05913 return 0; 05914 }
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 2930 of file chan_sip.c.
References ahp, ast_copy_string(), ast_get_srv(), ast_gethostbyname(), ast_log(), ast_string_field_set, ASTOBJ_UNREF, create_addr_from_peer(), find_peer(), hp, portno, sip_pvt::recv, sip_pvt::sa, sip_destroy_peer(), STANDARD_SIP_PORT, sip_pvt::timer_t1, and sip_peer::tohost.
02931 { 02932 struct hostent *hp; 02933 struct ast_hostent ahp; 02934 struct sip_peer *p; 02935 char *port; 02936 int portno; 02937 char host[MAXHOSTNAMELEN], *hostn; 02938 char peer[256]; 02939 02940 ast_copy_string(peer, opeer, sizeof(peer)); 02941 port = strchr(peer, ':'); 02942 if (port) 02943 *port++ = '\0'; 02944 dialog->sa.sin_family = AF_INET; 02945 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 02946 p = find_peer(peer, NULL, 1, 0); 02947 02948 if (p) { 02949 int res = create_addr_from_peer(dialog, p); 02950 if (port) { 02951 portno = atoi(port); 02952 dialog->sa.sin_port = dialog->recv.sin_port = htons(portno); 02953 } 02954 ASTOBJ_UNREF(p, sip_destroy_peer); 02955 return res; 02956 } 02957 hostn = peer; 02958 portno = port ? atoi(port) : STANDARD_SIP_PORT; 02959 if (srvlookup) { 02960 char service[MAXHOSTNAMELEN]; 02961 int tportno; 02962 int ret; 02963 02964 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 02965 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 02966 if (ret > 0) { 02967 hostn = host; 02968 portno = tportno; 02969 } 02970 } 02971 hp = ast_gethostbyname(hostn, &ahp); 02972 if (!hp) { 02973 ast_log(LOG_WARNING, "No such host: %s\n", peer); 02974 return -1; 02975 } 02976 ast_string_field_set(dialog, tohost, peer); 02977 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 02978 dialog->sa.sin_port = htons(portno); 02979 dialog->recv = dialog->sa; 02980 return 0; 02981 }
Create address structure from peer reference. return -1 on error, 0 on success.
Definition at line 2819 of file chan_sip.c.
References sip_peer::addr, sip_peer::allowtransfer, sip_pvt::allowtransfer, ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_destroy(), ast_udptl_get_error_correction_scheme(), sip_peer::auth, sip_peer::autoframing, sip_pvt::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_pvt::callgroup, sip_pvt::callid, t38properties::capability, sip_peer::capability, sip_pvt::capability, sip_peer::context, context, sip_peer::defaddr, do_setnat(), sip_peer::flags, sip_pvt::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_request::headers, sip_pvt::initreq, t38properties::jointcapability, sip_pvt::jointnoncodeccapability, language, sip_peer::language, sip_peer::lastms, LOG_DEBUG, sip_peer::maxcallbitrate, sip_pvt::maxcallbitrate, sip_peer::maxms, sip_pvt::maxtime, sip_peer::md5secret, sip_peer::mohinterpret, mohinterpret, sip_peer::mohsuggest, mohsuggest, sip_peer::name, sip_pvt::noncodeccapability, option_debug, sip_pvt::peerauth, sip_peer::pickupgroup, sip_pvt::pickupgroup, sip_peer::prefs, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_pvt::rtptimeout, sip_peer::rtptimeout, sip_pvt::sa, sip_peer::secret, SIP_CALL_LIMIT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_NAT, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_TCP, SIP_PAGE2_TCP_CONNECTED, SIP_PAGE2_VIDEOSUPPORT, sip_peer::sockfd, sip_pvt::sockfd, sip_pvt::t38, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, sip_pvt::timer_t1, sip_pvt::tohost, sip_peer::tohost, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, username, sip_peer::username, and sip_pvt::vrtp.
Referenced by create_addr(), and sip_send_mwi_to_peer().
02820 { 02821 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 02822 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 02823 dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr; 02824 dialog->recv = dialog->sa; 02825 } else 02826 return -1; 02827 02828 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 02829 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 02830 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_TCP | SIP_PAGE2_TCP_CONNECTED); 02831 dialog->sockfd = peer->sockfd; 02832 dialog->capability = peer->capability; 02833 if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) { 02834 ast_rtp_destroy(dialog->vrtp); 02835 dialog->vrtp = NULL; 02836 } 02837 dialog->prefs = peer->prefs; 02838 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) { 02839 dialog->t38.capability = global_t38_capability; 02840 if (dialog->udptl) { 02841 if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC ) 02842 dialog->t38.capability |= T38FAX_UDP_EC_FEC; 02843 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY ) 02844 dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 02845 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE ) 02846 dialog->t38.capability |= T38FAX_UDP_EC_NONE; 02847 dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 02848 if (option_debug > 1) 02849 ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability); 02850 } 02851 dialog->t38.jointcapability = dialog->t38.capability; 02852 } else if (dialog->udptl) { 02853 ast_udptl_destroy(dialog->udptl); 02854 dialog->udptl = NULL; 02855 } 02856 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE ); 02857 02858 if (dialog->rtp) { 02859 ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 02860 ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 02861 ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); 02862 ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); 02863 ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); 02864 /* Set Frame packetization */ 02865 ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); 02866 dialog->autoframing = peer->autoframing; 02867 } 02868 if (dialog->vrtp) { 02869 ast_rtp_setdtmf(dialog->vrtp, 0); 02870 ast_rtp_setdtmfcompensate(dialog->vrtp, 0); 02871 ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); 02872 ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); 02873 ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); 02874 } 02875 02876 ast_string_field_set(dialog, peername, peer->name); 02877 ast_string_field_set(dialog, authname, peer->username); 02878 ast_string_field_set(dialog, username, peer->username); 02879 ast_string_field_set(dialog, peersecret, peer->secret); 02880 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 02881 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 02882 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 02883 ast_string_field_set(dialog, tohost, peer->tohost); 02884 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 02885 if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 02886 char *tmpcall; 02887 char *c; 02888 tmpcall = ast_strdupa(dialog->callid); 02889 c = strchr(tmpcall, '@'); 02890 if (c) { 02891 *c = '\0'; 02892 ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain); 02893 } 02894 } 02895 if (ast_strlen_zero(dialog->tohost)) 02896 ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr)); 02897 if (!ast_strlen_zero(peer->fromdomain)) 02898 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 02899 if (!ast_strlen_zero(peer->fromuser)) 02900 ast_string_field_set(dialog, fromuser, peer->fromuser); 02901 if (!ast_strlen_zero(peer->language)) 02902 ast_string_field_set(dialog, language, peer->language); 02903 dialog->maxtime = peer->maxms; 02904 dialog->callgroup = peer->callgroup; 02905 dialog->pickupgroup = peer->pickupgroup; 02906 dialog->peerauth = peer->auth; 02907 dialog->allowtransfer = peer->allowtransfer; 02908 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 02909 /* Minimum is settable or default to 100 ms */ 02910 if (peer->maxms && peer->lastms) 02911 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 02912 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 02913 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 02914 dialog->noncodeccapability |= AST_RTP_DTMF; 02915 else 02916 dialog->noncodeccapability &= ~AST_RTP_DTMF; 02917 dialog->jointnoncodeccapability = dialog->noncodeccapability; 02918 ast_string_field_set(dialog, context, peer->context); 02919 dialog->rtptimeout = peer->rtptimeout; 02920 if (peer->call_limit) 02921 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 02922 dialog->maxcallbitrate = peer->maxcallbitrate; 02923 02924 return 0; 02925 }
static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 8072 of file chan_sip.c.
References ast_db_del(), ast_test_flag, ast_update_realtime(), sip_peer::flags, global_flags, sip_peer::name, SIP_PAGE2_IGNOREREGEXPIRE, and SIP_PAGE2_RT_FROMCONTACT.
Referenced by build_peer(), expire_register(), and parse_register_contact().
08073 { 08074 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 08075 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08076 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL); 08077 else 08078 ast_db_del("SIP/Registry", peer->name); 08079 } 08080 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 6923 of file chan_sip.c.
References ast_log(), ast_skip_blanks(), ast_skip_nonblanks(), ast_trim_blanks(), sip_request::header, sip_request::rlPart1, and sip_request::rlPart2.
Referenced by parse_request().
06924 { 06925 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 06926 06927 if (!*e) 06928 return -1; 06929 req->rlPart1 = e; /* method or protocol */ 06930 e = ast_skip_nonblanks(e); 06931 if (*e) 06932 *e++ = '\0'; 06933 /* Get URI or status code */ 06934 e = ast_skip_blanks(e); 06935 if ( !*e ) 06936 return -1; 06937 ast_trim_blanks(e); 06938 06939 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 06940 if (strlen(e) < 3) /* status code is 3 digits */ 06941 return -1; 06942 req->rlPart2 = e; 06943 } else { /* We have a request */ 06944 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 06945 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 06946 e++; 06947 if (!*e) 06948 return -1; 06949 } 06950 req->rlPart2 = e; /* URI */ 06951 e = ast_skip_nonblanks(e); 06952 if (*e) 06953 *e++ = '\0'; 06954 e = ast_skip_blanks(e); 06955 if (strcasecmp(e, "SIP/2.0") ) { 06956 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 06957 return -1; 06958 } 06959 } 06960 return 1; 06961 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 16325 of file chan_sip.c.
References __sip_destroy(), ast_channel_trylock, ast_channel_unlock, ast_io_add(), ast_io_change(), AST_IO_IN, ast_io_remove(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_rtp_get_rtpholdtimeout(), ast_rtp_get_rtpkeepalive(), ast_rtp_get_rtptimeout(), ast_rtp_sendcng(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtptimeout(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, ast_verbose(), DEADLOCK_AVOIDANCE, FALSE, sip_pvt::flags, iflist, iflock, io, sip_pvt::lock, LOG_NOTICE, sip_pvt::next, option_verbose, sip_pvt::owner, sip_pvt::packets, sip_do_reload(), SIP_NEEDDESTROY, sip_reload_lock, sipsock, sipsock_read(), siptcpsock, siptcpsock_accept(), t, T38_ENABLED, and VERBOSE_PREFIX_1.
16326 { 16327 int res; 16328 struct sip_pvt *sip; 16329 struct sip_peer *peer = NULL; 16330 time_t t; 16331 int fastrestart = FALSE; 16332 int lastpeernum = -1; 16333 int curpeernum; 16334 int reloading; 16335 16336 /* Add an I/O event to our SIP UDP socket */ 16337 if (sipsock > -1) 16338 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 16339 if (siptcpsock > -1) 16340 siptcpsock_read_id = ast_io_add(io, siptcpsock, siptcpsock_accept, AST_IO_IN, NULL); 16341 16342 /* From here on out, we die whenever asked */ 16343 for(;;) { 16344 /* Check for a reload request */ 16345 ast_mutex_lock(&sip_reload_lock); 16346 reloading = sip_reloading; 16347 sip_reloading = FALSE; 16348 ast_mutex_unlock(&sip_reload_lock); 16349 if (reloading) { 16350 if (option_verbose > 0) 16351 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 16352 sip_do_reload(sip_reloadreason); 16353 16354 /* Change the I/O fd of our UDP socket */ 16355 if (sipsock > -1) { 16356 if (sipsock_read_id) 16357 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 16358 else 16359 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 16360 } else if (sipsock_read_id) { 16361 ast_io_remove(io, sipsock_read_id); 16362 sipsock_read_id = NULL; 16363 } 16364 16365 if (siptcpsock > -1) { 16366 if (siptcpsock_read_id) 16367 siptcpsock_read_id = ast_io_change(io, siptcpsock_read_id, siptcpsock, NULL, 0, NULL); 16368 else 16369 siptcpsock_read_id = ast_io_add(io, siptcpsock, siptcpsock_accept, AST_IO_IN, NULL); 16370 } 16371 } 16372 restartsearch: 16373 /* Check for interfaces needing to be killed */ 16374 ast_mutex_lock(&iflock); 16375 t = time(NULL); 16376 /* don't scan the interface list if it hasn't been a reasonable period 16377 of time since the last time we did it (when MWI is being sent, we can 16378 get back to this point every millisecond or less) 16379 */ 16380 for (sip = iflist; !fastrestart && sip; sip = sip->next) { 16381 /*! \note If we can't get a lock on an interface, skip it and come 16382 * back later. Note that there is the possibility of a deadlock with 16383 * sip_hangup otherwise, because sip_hangup is called with the channel 16384 * locked first, and the iface lock is attempted second. 16385 */ 16386 if (ast_mutex_trylock(&sip->lock)) 16387 continue; 16388 16389 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 16390 if (sip->rtp && sip->owner && 16391 (sip->owner->_state == AST_STATE_UP) && 16392 !sip->redirip.sin_addr.s_addr && 16393 sip->t38.state != T38_ENABLED) { 16394 if (sip->lastrtptx && 16395 ast_rtp_get_rtpkeepalive(sip->rtp) && 16396 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) { 16397 /* Need to send an empty RTP packet */ 16398 sip->lastrtptx = time(NULL); 16399 ast_rtp_sendcng(sip->rtp, 0); 16400 } 16401 if (sip->lastrtprx && 16402 (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) && 16403 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) { 16404 /* Might be a timeout now -- see if we're on hold */ 16405 struct sockaddr_in sin; 16406 ast_rtp_get_peer(sip->rtp, &sin); 16407 if (sin.sin_addr.s_addr || 16408 (ast_rtp_get_rtpholdtimeout(sip->rtp) && 16409 (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) { 16410 /* Needs a hangup */ 16411 if (ast_rtp_get_rtptimeout(sip->rtp)) { 16412 while (sip->owner && ast_channel_trylock(sip->owner)) { 16413 DEADLOCK_AVOIDANCE(&sip->lock); 16414 } 16415 if (sip->owner) { 16416 ast_log(LOG_NOTICE, 16417 "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 16418 sip->owner->name, 16419 (long) (t - sip->lastrtprx)); 16420 /* Issue a softhangup */ 16421 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 16422 ast_channel_unlock(sip->owner); 16423 /* forget the timeouts for this call, since a hangup 16424 has already been requested and we don't want to 16425 repeatedly request hangups 16426 */ 16427 ast_rtp_set_rtptimeout(sip->rtp, 0); 16428 ast_rtp_set_rtpholdtimeout(sip->rtp, 0); 16429 if (sip->vrtp) { 16430 ast_rtp_set_rtptimeout(sip->vrtp, 0); 16431 ast_rtp_set_rtpholdtimeout(sip->vrtp, 0); 16432 } 16433 } 16434 } 16435 } 16436 } 16437 } 16438 /* If we have sessions that needs to be destroyed, do it now */ 16439 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && 16440 !sip->owner) { 16441 ast_mutex_unlock(&sip->lock); 16442 __sip_destroy(sip, 1); 16443 ast_mutex_unlock(&iflock); 16444 usleep(1); 16445 goto restartsearch; 16446 } 16447 ast_mutex_unlock(&sip->lock); 16448 } 16449 ast_mutex_unlock(&iflock); 16450 16451 /* XXX TODO The scheduler usage in this module does not have sufficient 16452 * synchronization being done between running the scheduler and places 16453 * scheduling tasks. As it is written, any scheduled item may not run 16454 * any sooner than about 1 second, regardless of whether a sooner time 16455 * was asked for. */ 16456 16457 pthread_testcancel(); 16458 /* Wait for sched or io */ 16459 res = ast_sched_wait(sched); 16460 if ((res < 0) || (res > 1000)) 16461 res = 1000; 16462 /* If we might need to send more mailboxes, don't wait long at all.*/ 16463 if (fastrestart) 16464 res = 1; 16465 res = ast_io_wait(io, res); 16466 if (option_debug && res > 20) 16467 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 16468 ast_mutex_lock(&monlock); 16469 res = ast_sched_runq(sched); 16470 if (option_debug && res >= 20) 16471 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 16472 16473 /* Send MWI notifications to peers - static and cached realtime peers */ 16474 t = time(NULL); 16475 fastrestart = FALSE; 16476 curpeernum = 0; 16477 peer = NULL; 16478 /* Find next peer that needs mwi */ 16479 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 16480 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 16481 fastrestart = TRUE; 16482 lastpeernum = curpeernum; 16483 peer = ASTOBJ_REF(iterator); 16484 }; 16485 curpeernum++; 16486 } while (0) 16487 ); 16488 /* Send MWI to the peer */ 16489 if (peer) { 16490 ASTOBJ_WRLOCK(peer); 16491 sip_send_mwi_to_peer(peer); 16492 ASTOBJ_UNLOCK(peer); 16493 ASTOBJ_UNREF(peer,sip_destroy_peer); 16494 } else { 16495 /* Reset where we come from */ 16496 lastpeernum = -1; 16497 } 16498 ast_mutex_unlock(&monlock); 16499 } 16500 /* Never reached */ 16501 return NULL; 16502 16503 }
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 11729 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().
11730 { 11731 char digest[1024]; 11732 11733 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 11734 return -2; 11735 11736 p->authtries++; 11737 if (option_debug > 1) 11738 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 11739 memset(digest, 0, sizeof(digest)); 11740 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 11741 /* No way to authenticate */ 11742 return -1; 11743 } 11744 /* Now we have a reply digest */ 11745 p->options->auth = digest; 11746 p->options->authheader = respheader; 11747 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 11748 }
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 11708 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().
11709 { 11710 char digest[1024]; 11711 p->authtries++; 11712 memset(digest,0,sizeof(digest)); 11713 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 11714 /* There's nothing to use for authentication */ 11715 /* No digest challenge in request */ 11716 if (sip_debug_test_pvt(p) && p->registry) 11717 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 11718 /* No old challenge */ 11719 return -1; 11720 } 11721 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 11722 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 11723 if (sip_debug_test_pvt(p) && p->registry) 11724 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 11725 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 11726 }
static void do_setnat | ( | struct sip_pvt * | p, | |
int | natflags | |||
) | [static] |
Set nat mode on the various data sockets.
Definition at line 2795 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().
02796 { 02797 const char *mode = natflags ? "On" : "Off"; 02798 02799 if (p->rtp) { 02800 if (option_debug) 02801 ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode); 02802 ast_rtp_setnat(p->rtp, natflags); 02803 } 02804 if (p->vrtp) { 02805 if (option_debug) 02806 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode); 02807 ast_rtp_setnat(p->vrtp, natflags); 02808 } 02809 if (p->udptl) { 02810 if (option_debug) 02811 ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode); 02812 ast_udptl_setnat(p->udptl, natflags); 02813 } 02814 }
static int does_peer_need_mwi | ( | struct sip_peer * | peer | ) | [static] |
Check whether peer needs a new MWI notification check.
Definition at line 16304 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.
16305 { 16306 time_t t = time(NULL); 16307 16308 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 16309 !peer->mwipvt) { /* We don't have a subscription */ 16310 peer->lastmsgcheck = t; /* Reset timer */ 16311 return FALSE; 16312 } 16313 16314 if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime) 16315 return TRUE; 16316 16317 return FALSE; 16318 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 10555 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
10556 { 10557 switch (mode) { 10558 case SIP_DOMAIN_AUTO: 10559 return "[Automatic]"; 10560 case SIP_DOMAIN_CONFIG: 10561 return "[Configured]"; 10562 } 10563 10564 return ""; 10565 }
static const char * dtmfmode2str | ( | int | mode | ) | const [static] |
Convert DTMF mode to printable string.
Definition at line 10335 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().
10336 { 10337 switch (mode) { 10338 case SIP_DTMF_RFC2833: 10339 return "rfc2833"; 10340 case SIP_DTMF_INFO: 10341 return "info"; 10342 case SIP_DTMF_INBAND: 10343 return "inband"; 10344 case SIP_DTMF_AUTO: 10345 return "auto"; 10346 } 10347 return "<error>"; 10348 }
static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 8083 of file chan_sip.c.
References sip_peer::addr, ast_clear_flag, ast_device_state_changed(), ast_test_flag, ASTOBJ_CONTAINER_UNLINK, ASTOBJ_UNREF, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, FALSE, sip_peer::flags, manager_event(), sip_peer::name, peerl, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RTAUTOCLEAR, SIP_PAGE2_SELFDESTRUCT, SIP_PAGE2_TCP_CONNECTED, and sip_peer::sockfd.
Referenced by parse_register_contact(), and reg_source_db().
08084 { 08085 struct sip_peer *peer = (struct sip_peer *)data; 08086 08087 if (!peer) /* Hmmm. We have no peer. Weird. */ 08088 return 0; 08089 08090 memset(&peer->addr, 0, sizeof(peer->addr)); 08091 if (peer->sockfd > 0) { 08092 close(peer->sockfd); 08093 ast_clear_flag(&peer->flags[1], SIP_PAGE2_TCP_CONNECTED); 08094 } 08095 08096 destroy_association(peer); /* remove registration data from storage */ 08097 08098 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08099 register_peer_exten(peer, FALSE); /* Remove regexten */ 08100 peer->expire = -1; 08101 ast_device_state_changed("SIP/%s", peer->name); 08102 08103 /* Do we need to release this peer from memory? 08104 Only for realtime peers and autocreated peers 08105 */ 08106 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) || 08107 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 08108 struct sip_peer *peer_ptr = peer_ptr; 08109 peer_ptr = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); 08110 if (peer_ptr) { 08111 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08112 } 08113 } 08114 08115 ASTOBJ_UNREF(peer, sip_destroy_peer); 08116 08117 return 0; 08118 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 7013 of file chan_sip.c.
References ast_copy_string(), ast_string_field_set, ast_strlen_zero(), get_header(), get_in_brackets(), and SIPBUFSIZE.
Referenced by handle_request(), and handle_request_invite().
07014 { 07015 char stripped[SIPBUFSIZE]; 07016 char *c; 07017 07018 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 07019 c = get_in_brackets(stripped); 07020 c = strsep(&c, ";"); /* trim ; and beyond */ 07021 if (!ast_strlen_zero(c)) 07022 ast_string_field_set(p, uri, c); 07023 }
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 4318 of file chan_sip.c.
References aliases.
04319 { 04320 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 04321 static const struct cfalias { 04322 char * const fullname; 04323 char * const shortname; 04324 } aliases[] = { 04325 { "Content-Type", "c" }, 04326 { "Content-Encoding", "e" }, 04327 { "From", "f" }, 04328 { "Call-ID", "i" }, 04329 { "Contact", "m" }, 04330 { "Content-Length", "l" }, 04331 { "Subject", "s" }, 04332 { "To", "t" }, 04333 { "Supported", "k" }, 04334 { "Refer-To", "r" }, 04335 { "Referred-By", "b" }, 04336 { "Allow-Events", "u" }, 04337 { "Event", "o" }, 04338 { "Via", "v" }, 04339 { "Accept-Contact", "a" }, 04340 { "Reject-Contact", "j" }, 04341 { "Request-Disposition", "d" }, 04342 { "Session-Expires", "x" }, 04343 { "Identity", "y" }, 04344 { "Identity-Info", "n" }, 04345 }; 04346 int x; 04347 04348 for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 04349 if (!strcasecmp(aliases[x].fullname, name)) 04350 return aliases[x].shortname; 04351 04352 return _default; 04353 }
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 4681 of file chan_sip.c.
References ast_log(), ast_mutex_lock(), ast_set_flag, ast_strlen_zero(), ast_test_flag, sip_pvt::callid, FALSE, sip_pvt::flags, sip_pvt::from, get_header(), gettag(), iflist, iflock, LOG_DEBUG, sip_request::method, sip_pvt::next, option_debug, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_WITH_TOTAG, SIP_REGISTER, SIP_RESPONSE, sip_pvt::tag, and sip_pvt::theirtag.
Referenced by sipsock_read().
04682 { 04683 struct sip_pvt *p = NULL; 04684 char *tag = ""; /* note, tag is never NULL */ 04685 char totag[128]; 04686 char fromtag[128]; 04687 const char *callid = get_header(req, "Call-ID"); 04688 const char *from = get_header(req, "From"); 04689 const char *to = get_header(req, "To"); 04690 const char *cseq = get_header(req, "Cseq"); 04691 04692 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 04693 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 04694 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 04695 ast_strlen_zero(from) || ast_strlen_zero(cseq)) 04696 return NULL; /* Invalid packet */ 04697 04698 if (pedanticsipchecking) { 04699 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 04700 we need more to identify a branch - so we have to check branch, from 04701 and to tags to identify a call leg. 04702 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 04703 in sip.conf 04704 */ 04705 if (gettag(req, "To", totag, sizeof(totag))) 04706 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 04707 gettag(req, "From", fromtag, sizeof(fromtag)); 04708 04709 tag = (req->method == SIP_RESPONSE) ? totag : fromtag; 04710 04711 if (option_debug > 4 ) 04712 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); 04713 } 04714 04715 ast_mutex_lock(&iflock); 04716 for (p = iflist; p; p = p->next) { 04717 /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 04718 int found = FALSE; 04719 if (ast_strlen_zero(p->callid)) 04720 continue; 04721 if (req->method == SIP_REGISTER) 04722 found = (!strcmp(p->callid, callid)); 04723 else { 04724 found = !strcmp(p->callid, callid); 04725 if (pedanticsipchecking && found) { 04726 found = ast_strlen_zero(tag) || ast_strlen_zero(p->theirtag) || !ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED) || !strcmp(p->theirtag, tag); 04727 } 04728 } 04729 04730 if (option_debug > 4) 04731 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); 04732 04733 /* If we get a new request within an existing to-tag - check the to tag as well */ 04734 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 04735 if (p->tag[0] == '\0' && totag[0]) { 04736 /* We have no to tag, but they have. Wrong dialog */ 04737 found = FALSE; 04738 } else if (totag[0]) { /* Both have tags, compare them */ 04739 if (strcmp(totag, p->tag)) { 04740 found = FALSE; /* This is not our packet */ 04741 } 04742 } 04743 if (!found && option_debug > 4) 04744 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); 04745 } 04746 if (found) { 04747 /* Found the call */ 04748 ast_mutex_lock(&p->lock); 04749 ast_mutex_unlock(&iflock); 04750 return p; 04751 } 04752 } 04753 ast_mutex_unlock(&iflock); 04754 04755 /* See if the method is capable of creating a dialog */ 04756 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 04757 if (intended_method == SIP_REFER) { 04758 /* We do support REFER, but not outside of a dialog yet */ 04759 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 04760 } else if (intended_method == SIP_NOTIFY) { 04761 /* We do not support out-of-dialog NOTIFY either, 04762 like voicemail notification, so cancel that early */ 04763 transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); 04764 } else { 04765 /* Ok, time to create a new SIP dialog object, a pvt */ 04766 if ((p = sip_alloc(callid, sin, 1, intended_method))) { 04767 /* Ok, we've created a dialog, let's go and process it */ 04768 ast_mutex_lock(&p->lock); 04769 } else { 04770 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 04771 getting a dialog from sip_alloc. 04772 04773 Without a dialog we can't retransmit and handle ACKs and all that, but at least 04774 send an error message. 04775 04776 Sorry, we apologize for the inconvienience 04777 */ 04778 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 04779 if (option_debug > 3) 04780 ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 04781 } 04782 } 04783 return p; 04784 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 04785 /* A method we do not support, let's take it on the volley */ 04786 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 04787 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 04788 /* This is a request outside of a dialog that we don't know about 04789 ...never reply to an ACK! 04790 */ 04791 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 04792 } 04793 /* We do not respond to responses for dialogs that we don't know about, we just drop 04794 the session quickly */ 04795 04796 return p; 04797 }
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 2356 of file chan_sip.c.
References s.
Referenced by get_in_brackets().
02357 { 02358 char last_char = '\0'; 02359 const char *s; 02360 for (s = start; *s && s != lim; last_char = *s++) { 02361 if (*s == '"' && last_char != '\\') 02362 break; 02363 } 02364 return s; 02365 }
static struct sip_peer * find_peer | ( | const char * | peer, | |
struct sockaddr_in * | sin, | |||
int | realtime, | |||
int | devstate_only | |||
) | [static] |
Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name.
Definition at line 2707 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().
02708 { 02709 struct sip_peer *p = NULL; 02710 02711 if (peer) 02712 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 02713 else 02714 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); 02715 02716 if (!p && (realtime || devstate_only)) 02717 p = realtime_peer(peer, sin, devstate_only); 02718 02719 return p; 02720 }
static struct sip_auth * find_realm_authentication | ( | struct sip_auth * | authlist, | |
const char * | realm | |||
) | [static] |
Find authentication for a specific realm.
Definition at line 17144 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
17145 { 17146 struct sip_auth *a; 17147 17148 for (a = authlist; a; a = a->next) { 17149 if (!strcasecmp(a->realm, realm)) 17150 break; 17151 } 17152 17153 return a; 17154 }
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 5014 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), FALSE, get_header(), sip_request::line, sip_request::lines, sip_request::sdp_end, sip_request::sdp_start, and TRUE.
Referenced by handle_request(), handle_request_invite(), handle_response(), and handle_response_invite().
05015 { 05016 const char *content_type; 05017 const char *content_length; 05018 const char *search; 05019 char *boundary; 05020 unsigned int x; 05021 int boundaryisquoted = FALSE; 05022 int found_application_sdp = FALSE; 05023 int found_end_of_headers = FALSE; 05024 05025 content_length = get_header(req, "Content-Length"); 05026 05027 if (!ast_strlen_zero(content_length)) { 05028 if (sscanf(content_length, "%ud", &x) != 1) { 05029 ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length); 05030 return 0; 05031 } 05032 05033 /* Content-Length of zero means there can't possibly be an 05034 SDP here, even if the Content-Type says there is */ 05035 if (x == 0) 05036 return 0; 05037 } 05038 05039 content_type = get_header(req, "Content-Type"); 05040 05041 /* if the body contains only SDP, this is easy */ 05042 if (!strncasecmp(content_type, "application/sdp", 15)) { 05043 req->sdp_start = 0; 05044 req->sdp_end = req->lines; 05045 return req->lines ? 1 : 0; 05046 } 05047 05048 /* if it's not multipart/mixed, there cannot be an SDP */ 05049 if (strncasecmp(content_type, "multipart/mixed", 15)) 05050 return 0; 05051 05052 /* if there is no boundary marker, it's invalid */ 05053 if ((search = strcasestr(content_type, ";boundary="))) 05054 search += 10; 05055 else if ((search = strcasestr(content_type, "; boundary="))) 05056 search += 11; 05057 else 05058 return 0; 05059 05060 if (ast_strlen_zero(search)) 05061 return 0; 05062 05063 /* If the boundary is quoted with ", remove quote */ 05064 if (*search == '\"') { 05065 search++; 05066 boundaryisquoted = TRUE; 05067 } 05068 05069 /* make a duplicate of the string, with two extra characters 05070 at the beginning */ 05071 boundary = ast_strdupa(search - 2); 05072 boundary[0] = boundary[1] = '-'; 05073 /* Remove final quote */ 05074 if (boundaryisquoted) 05075 boundary[strlen(boundary) - 1] = '\0'; 05076 05077 /* search for the boundary marker, the empty line delimiting headers from 05078 sdp part and the end boundry if it exists */ 05079 05080 for (x = 0; x < (req->lines ); x++) { 05081 if(!strncasecmp(req->line[x], boundary, strlen(boundary))){ 05082 if(found_application_sdp && found_end_of_headers){ 05083 req->sdp_end = x-1; 05084 return 1; 05085 } 05086 found_application_sdp = FALSE; 05087 } 05088 if(!strcasecmp(req->line[x], "Content-Type: application/sdp")) 05089 found_application_sdp = TRUE; 05090 05091 if(strlen(req->line[x]) == 0 ){ 05092 if(found_application_sdp && !found_end_of_headers){ 05093 req->sdp_start = x; 05094 found_end_of_headers = TRUE; 05095 } 05096 } 05097 } 05098 if(found_application_sdp && found_end_of_headers) { 05099 req->sdp_end = x; 05100 return TRUE; 05101 } 05102 return FALSE; 05103 }
static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 1700 of file chan_sip.c.
References ast_strlen_zero(), method_match(), and sip_methods.
Referenced by __sip_pretend_ack(), handle_response(), and sipsock_read().
01701 { 01702 int i, res = 0; 01703 01704 if (ast_strlen_zero(msg)) 01705 return 0; 01706 for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) { 01707 if (method_match(i, msg)) 01708 res = sip_methods[i].id; 01709 } 01710 return res; 01711 }
static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static] |
Find subscription type in array.
Definition at line 11044 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
11045 { 11046 int i; 11047 11048 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 11049 if (subscription_types[i].type == subtype) { 11050 return &subscription_types[i]; 11051 } 11052 } 11053 return &subscription_types[0]; 11054 }
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 2786 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.
02787 { 02788 struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name); 02789 if (!u && realtime) 02790 u = realtime_user(name); 02791 return u; 02792 }
static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 8473 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
08474 { 08475 struct sip_route *next; 08476 08477 while (route) { 08478 next = route->next; 08479 free(route); 08480 route = next; 08481 } 08482 }
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 12064 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), and check_sip_domain().
12065 { 12066 if (ast_strlen_zero(data)) { 12067 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 12068 return -1; 12069 } 12070 if (check_sip_domain(data, NULL, 0)) 12071 ast_copy_string(buf, data, len); 12072 else 12073 buf[0] = '\0'; 12074 return 0; 12075 }
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 12000 of file chan_sip.c.
References __get_header(), AST_APP_ARG, ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), sip_request::header, sip_pvt::initreq, sip_tech, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.
12001 { 12002 struct sip_pvt *p; 12003 const char *content = NULL; 12004 AST_DECLARE_APP_ARGS(args, 12005 AST_APP_ARG(header); 12006 AST_APP_ARG(number); 12007 ); 12008 int i, number, start = 0; 12009 12010 if (ast_strlen_zero(data)) { 12011 ast_log(LOG_WARNING, "This function requires a header name.\n"); 12012 return -1; 12013 } 12014 12015 ast_channel_lock(chan); 12016 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 12017 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 12018 ast_channel_unlock(chan); 12019 return -1; 12020 } 12021 12022 AST_STANDARD_APP_ARGS(args, data); 12023 if (!args.number) { 12024 number = 1; 12025 } else { 12026 sscanf(args.number, "%d", &number); 12027 if (number < 1) 12028 number = 1; 12029 } 12030 12031 p = chan->tech_pvt; 12032 12033 /* If there is no private structure, this channel is no longer alive */ 12034 if (!p) { 12035 ast_channel_unlock(chan); 12036 return -1; 12037 } 12038 12039 for (i = 0; i < number; i++) 12040 content = __get_header(&p->initreq, args.header, &start); 12041 12042 if (ast_strlen_zero(content)) { 12043 ast_channel_unlock(chan); 12044 return -1; 12045 } 12046 12047 ast_copy_string(buf, content, len); 12048 ast_channel_unlock(chan); 12049 12050 return 0; 12051 }
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 12183 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_inet_ntoa(), ast_log(), sip_pvt::from, sip_pvt::peername, sip_pvt::recv, sip_pvt::sa, sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::uri, and sip_pvt::useragent.
12184 { 12185 struct sip_pvt *p; 12186 12187 *buf = 0; 12188 12189 if (!data) { 12190 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 12191 return -1; 12192 } 12193 12194 ast_channel_lock(chan); 12195 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 12196 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 12197 ast_channel_unlock(chan); 12198 return -1; 12199 } 12200 12201 p = chan->tech_pvt; 12202 12203 /* If there is no private structure, this channel is no longer alive */ 12204 if (!p) { 12205 ast_channel_unlock(chan); 12206 return -1; 12207 } 12208 12209 if (!strcasecmp(data, "peerip")) { 12210 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 12211 } else if (!strcasecmp(data, "recvip")) { 12212 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 12213 } else if (!strcasecmp(data, "from")) { 12214 ast_copy_string(buf, p->from, len); 12215 } else if (!strcasecmp(data, "uri")) { 12216 ast_copy_string(buf, p->uri, len); 12217 } else if (!strcasecmp(data, "useragent")) { 12218 ast_copy_string(buf, p->useragent, len); 12219 } else if (!strcasecmp(data, "peername")) { 12220 ast_copy_string(buf, p->peername, len); 12221 } else if (!strcasecmp(data, "t38passthrough")) { 12222 if (p->t38.state == T38_DISABLED) 12223 ast_copy_string(buf, "0", sizeof("0")); 12224 else /* T38 is offered or enabled in this call */ 12225 ast_copy_string(buf, "1", sizeof("1")); 12226 } else { 12227 ast_channel_unlock(chan); 12228 return -1; 12229 } 12230 ast_channel_unlock(chan); 12231 12232 return 0; 12233 }
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 12089 of file chan_sip.c.
References sip_peer::accountcode, sip_peer::addr, ast_codec_pref_index(), ast_copy_string(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_peer::capability, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::expire, find_peer(), sip_peer::flags, sip_peer::inUse, sip_peer::language, sip_peer::mailbox, peer_status(), sip_peer::prefs, sip_peer::regexten, sip_destroy_peer(), SIP_PAGE2_DYNAMIC, and sip_peer::useragent.
12090 { 12091 struct sip_peer *peer; 12092 char *colname; 12093 12094 if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */ 12095 *colname++ = '\0'; 12096 else if ((colname = strchr(data, '|'))) 12097 *colname++ = '\0'; 12098 else 12099 colname = "ip"; 12100 12101 if (!(peer = find_peer(data, NULL, 1, 0))) 12102 return -1; 12103 12104 if (!strcasecmp(colname, "ip")) { 12105 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 12106 } else if (!strcasecmp(colname, "status")) { 12107 peer_status(peer, buf, len); 12108 } else if (!strcasecmp(colname, "language")) { 12109 ast_copy_string(buf, peer->language, len); 12110 } else if (!strcasecmp(colname, "regexten")) { 12111 ast_copy_string(buf, peer->regexten, len); 12112 } else if (!strcasecmp(colname, "limit")) { 12113 snprintf(buf, len, "%d", peer->call_limit); 12114 } else if (!strcasecmp(colname, "curcalls")) { 12115 snprintf(buf, len, "%d", peer->inUse); 12116 } else if (!strcasecmp(colname, "accountcode")) { 12117 ast_copy_string(buf, peer->accountcode, len); 12118 } else if (!strcasecmp(colname, "useragent")) { 12119 ast_copy_string(buf, peer->useragent, len); 12120 } else if (!strcasecmp(colname, "mailbox")) { 12121 ast_copy_string(buf, peer->mailbox, len); 12122 } else if (!strcasecmp(colname, "context")) { 12123 ast_copy_string(buf, peer->context, len); 12124 } else if (!strcasecmp(colname, "expire")) { 12125 snprintf(buf, len, "%d", peer->expire); 12126 } else if (!strcasecmp(colname, "dynamic")) { 12127 ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 12128 } else if (!strcasecmp(colname, "callerid_name")) { 12129 ast_copy_string(buf, peer->cid_name, len); 12130 } else if (!strcasecmp(colname, "callerid_num")) { 12131 ast_copy_string(buf, peer->cid_num, len); 12132 } else if (!strcasecmp(colname, "codecs")) { 12133 ast_getformatname_multiple(buf, len -1, peer->capability); 12134 } else if (!strncasecmp(colname, "codec[", 6)) { 12135 char *codecnum; 12136 int index = 0, codec = 0; 12137 12138 codecnum = colname + 6; /* move past the '[' */ 12139 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 12140 index = atoi(codecnum); 12141 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 12142 ast_copy_string(buf, ast_getformatname(codec), len); 12143 } else { 12144 buf[0] = '\0'; 12145 } 12146 } else { 12147 buf[0] = '\0'; 12148 } 12149 12150 ASTOBJ_UNREF(peer, sip_destroy_peer); 12151 12152 return 0; 12153 }
static char * generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 4508 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), and build_callid_registry().
04509 { 04510 long val[4]; 04511 int x; 04512 04513 for (x=0; x<4; x++) 04514 val[x] = ast_random(); 04515 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 04516 04517 return buf; 04518 }
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 9406 of file chan_sip.c.
References ast_canmatch_extension(), ast_copy_string(), ast_exists_extension(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), context, sip_pvt::context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, ast_channel::macrocontext, option_debug, sip_pvt::owner, pbx_builtin_getvar_helper(), sip_pvt::refer, sip_refer::refer_call, sip_refer::refer_contact, sip_refer::refer_to, sip_refer::refer_to_domain, sip_refer::referred_by, S_OR, sip_debug_test_pvt(), and sip_refer_allocate().
Referenced by handle_request_bye().
09407 { 09408 char tmp[256] = "", *c, *a; 09409 struct sip_request *req = oreq ? oreq : &p->initreq; 09410 struct sip_refer *referdata = NULL; 09411 const char *transfer_context = NULL; 09412 09413 if (!p->refer && !sip_refer_allocate(p)) 09414 return -1; 09415 09416 referdata = p->refer; 09417 09418 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 09419 c = get_in_brackets(tmp); 09420 09421 if (pedanticsipchecking) 09422 ast_uri_decode(c); 09423 09424 if (strncasecmp(c, "sip:", 4)) { 09425 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 09426 return -1; 09427 } 09428 c += 4; 09429 if ((a = strchr(c, ';'))) /* Remove arguments */ 09430 *a = '\0'; 09431 09432 if ((a = strchr(c, '@'))) { /* Separate Domain */ 09433 *a++ = '\0'; 09434 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 09435 } 09436 09437 if (sip_debug_test_pvt(p)) 09438 ast_verbose("Looking for %s in %s\n", c, p->context); 09439 09440 if (p->owner) /* Mimic behaviour in res_features.c */ 09441 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 09442 09443 /* By default, use the context in the channel sending the REFER */ 09444 if (ast_strlen_zero(transfer_context)) { 09445 transfer_context = S_OR(p->owner->macrocontext, 09446 S_OR(p->context, default_context)); 09447 } 09448 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 09449 /* This is a blind transfer */ 09450 if (option_debug) 09451 ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 09452 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 09453 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 09454 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 09455 referdata->refer_call = NULL; 09456 /* Set new context */ 09457 ast_string_field_set(p, context, transfer_context); 09458 return 0; 09459 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 09460 return 1; 09461 } 09462 09463 return -1; 09464 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
Get a specific line from the message body.
Definition at line 4302 of file chan_sip.c.
References get_body_by_line(), len(), sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
04303 { 04304 int x; 04305 int len = strlen(name); 04306 char *r; 04307 04308 for (x = 0; x < req->lines; x++) { 04309 r = get_body_by_line(req->line[x], name, len); 04310 if (r[0] != '\0') 04311 return r; 04312 } 04313 04314 return ""; 04315 }
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 4268 of file chan_sip.c.
References ast_skip_blanks().
Referenced by get_body(), and get_sdp_iterate().
04269 { 04270 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') 04271 return ast_skip_blanks(line + nameLen + 1); 04272 04273 return ""; 04274 }
static char * get_calleridname | ( | const char * | input, | |
char * | output, | |||
size_t | outputsize | |||
) | [static] |
Get caller id name from SIP headers.
Definition at line 9518 of file chan_sip.c.
References ast_copy_string(), and ast_skip_blanks().
Referenced by check_user_full().
09519 { 09520 const char *end = strchr(input,'<'); /* first_bracket */ 09521 const char *tmp = strchr(input,'"'); /* first quote */ 09522 int bytes = 0; 09523 int maxbytes = outputsize - 1; 09524 09525 if (!end || end == input) /* we require a part in brackets */ 09526 return NULL; 09527 09528 end--; /* move just before "<" */ 09529 09530 if (tmp && tmp <= end) { 09531 /* The quote (tmp) precedes the bracket (end+1). 09532 * Find the matching quote and return the content. 09533 */ 09534 end = strchr(tmp+1, '"'); 09535 if (!end) 09536 return NULL; 09537 bytes = (int) (end - tmp); 09538 /* protect the output buffer */ 09539 if (bytes > maxbytes) 09540 bytes = maxbytes; 09541 ast_copy_string(output, tmp + 1, bytes); 09542 } else { 09543 /* No quoted string, or it is inside brackets. */ 09544 /* clear the empty characters in the begining*/ 09545 input = ast_skip_blanks(input); 09546 /* clear the empty characters in the end */ 09547 while(*end && *end < 33 && end > input) 09548 end--; 09549 if (end >= input) { 09550 bytes = (int) (end - input) + 2; 09551 /* protect the output buffer */ 09552 if (bytes > maxbytes) 09553 bytes = maxbytes; 09554 ast_copy_string(output, input, bytes); 09555 } else 09556 return NULL; 09557 } 09558 return output; 09559 }
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 9053 of file chan_sip.c.
References ast_canmatch_extension(), ast_copy_string(), ast_exists_extension(), ast_get_hint(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), check_sip_domain(), sip_pvt::cid_num, sip_pvt::context, context, sip_pvt::domain, exten, sip_pvt::exten, get_header(), get_in_brackets(), global_flags, sip_pvt::initreq, LOG_DEBUG, sip_request::method, option_debug, sip_request::rlPart2, S_OR, sip_debug_test_pvt(), SIP_INVITE, sip_methods, SIP_PAGE2_ALLOWOVERLAP, SIP_REFER, SIP_SUBSCRIBE, and sip_pvt::subscribecontext.
Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe().
09054 { 09055 char tmp[256] = "", *uri, *a; 09056 char tmpf[256] = "", *from; 09057 struct sip_request *req; 09058 char *colon; 09059 char *decoded_uri; 09060 09061 req = oreq; 09062 if (!req) 09063 req = &p->initreq; 09064 09065 /* Find the request URI */ 09066 if (req->rlPart2) 09067 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 09068 09069 if (pedanticsipchecking) 09070 ast_uri_decode(tmp); 09071 09072 uri = get_in_brackets(tmp); 09073 09074 if (strncasecmp(uri, "sip:", 4)) { 09075 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 09076 return -1; 09077 } 09078 uri += 4; 09079 09080 /* Now find the From: caller ID and name */ 09081 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 09082 if (!ast_strlen_zero(tmpf)) { 09083 if (pedanticsipchecking) 09084 ast_uri_decode(tmpf); 09085 from = get_in_brackets(tmpf); 09086 } else { 09087 from = NULL; 09088 } 09089 09090 if (!ast_strlen_zero(from)) { 09091 if (strncasecmp(from, "sip:", 4)) { 09092 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 09093 return -1; 09094 } 09095 from += 4; 09096 if ((a = strchr(from, '@'))) 09097 *a++ = '\0'; 09098 else 09099 a = from; /* just a domain */ 09100 from = strsep(&from, ";"); /* Remove userinfo options */ 09101 a = strsep(&a, ";"); /* Remove URI options */ 09102 ast_string_field_set(p, fromdomain, a); 09103 } 09104 09105 /* Skip any options and find the domain */ 09106 09107 /* Get the target domain */ 09108 if ((a = strchr(uri, '@'))) { 09109 *a++ = '\0'; 09110 } else { /* No username part */ 09111 a = uri; 09112 uri = "s"; /* Set extension to "s" */ 09113 } 09114 colon = strchr(a, ':'); /* Remove :port */ 09115 if (colon) 09116 *colon = '\0'; 09117 09118 uri = strsep(&uri, ";"); /* Remove userinfo options */ 09119 a = strsep(&a, ";"); /* Remove URI options */ 09120 09121 ast_string_field_set(p, domain, a); 09122 09123 if (!AST_LIST_EMPTY(&domain_list)) { 09124 char domain_context[AST_MAX_EXTENSION]; 09125 09126 domain_context[0] = '\0'; 09127 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 09128 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 09129 if (option_debug) 09130 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 09131 return -2; 09132 } 09133 } 09134 /* If we have a context defined, overwrite the original context */ 09135 if (!ast_strlen_zero(domain_context)) 09136 ast_string_field_set(p, context, domain_context); 09137 } 09138 09139 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 09140 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) 09141 ast_string_field_set(p, context, p->subscribecontext); 09142 09143 if (sip_debug_test_pvt(p)) 09144 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 09145 09146 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 09147 if (req->method == SIP_SUBSCRIBE) { 09148 char hint[AST_MAX_EXTENSION]; 09149 return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1); 09150 } else { 09151 decoded_uri = ast_strdupa(uri); 09152 ast_uri_decode(decoded_uri); 09153 /* Check the dialplan for the username part of the request URI, 09154 the domain will be stored in the SIPDOMAIN variable 09155 Since extensions.conf can have unescaped characters, try matching a decoded 09156 uri in addition to the non-decoded uri 09157 Return 0 if we have a matching extension */ 09158 if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) || ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) || 09159 !strcmp(decoded_uri, ast_pickup_ext())) { 09160 if (!oreq) 09161 ast_string_field_set(p, exten, decoded_uri); 09162 return 0; 09163 } 09164 } 09165 09166 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 09167 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 09168 ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))) || 09169 !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri))) { 09170 return 1; 09171 } 09172 09173 return -1; 09174 }
static const char * get_header | ( | const struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get header from SIP request.
Definition at line 4391 of file chan_sip.c.
References __get_header().
04392 { 04393 int start = 0; 04394 return __get_header(req, name, &start); 04395 }
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 2378 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().
02379 { 02380 const char *parse = tmp; 02381 char *first_bracket; 02382 02383 /* 02384 * Skip any quoted text until we find the part in brackets. 02385 * On any error give up and return the full string. 02386 */ 02387 while ( (first_bracket = strchr(parse, '<')) ) { 02388 char *first_quote = strchr(parse, '"'); 02389 02390 if (!first_quote || first_quote > first_bracket) 02391 break; /* no need to look at quoted part */ 02392 /* the bracket is within quotes, so ignore it */ 02393 parse = find_closing_quote(first_quote + 1, NULL); 02394 if (!*parse) { /* not found, return full string ? */ 02395 /* XXX or be robust and return in-bracket part ? */ 02396 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 02397 break; 02398 } 02399 parse++; 02400 } 02401 if (first_bracket) { 02402 char *second_bracket = strchr(first_bracket + 1, '>'); 02403 if (second_bracket) { 02404 *second_bracket = '\0'; 02405 tmp = first_bracket + 1; 02406 } else { 02407 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 02408 } 02409 } 02410 return tmp; 02411 }
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 9928 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_notify(), and receive_message().
09929 { 09930 int x; 09931 int y; 09932 09933 buf[0] = '\0'; 09934 y = len - strlen(buf) - 5; 09935 if (y < 0) 09936 y = 0; 09937 for (x=0;x<req->lines;x++) { 09938 strncat(buf, req->line[x], y); /* safe */ 09939 y -= strlen(req->line[x]) + 1; 09940 if (y < 0) 09941 y = 0; 09942 if (y != 0) 09943 strcat(buf, "\n"); /* safe */ 09944 } 09945 return 0; 09946 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Get referring dnis.
Definition at line 9024 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_verbose(), get_header(), get_in_brackets(), sip_pvt::initreq, and sip_debug_test_pvt().
Referenced by handle_request_invite().
09025 { 09026 char tmp[256], *c, *a; 09027 struct sip_request *req; 09028 09029 req = oreq; 09030 if (!req) 09031 req = &p->initreq; 09032 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 09033 if (ast_strlen_zero(tmp)) 09034 return 0; 09035 c = get_in_brackets(tmp); 09036 if (strncasecmp(c, "sip:", 4)) { 09037 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 09038 return -1; 09039 } 09040 c += 4; 09041 a = c; 09042 strsep(&a, "@;"); /* trim anything after @ or ; */ 09043 if (sip_debug_test_pvt(p)) 09044 ast_verbose("RDNIS is %s\n", c); 09045 ast_string_field_set(p, rdnis, c); 09046 09047 return 0; 09048 }
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 9240 of file chan_sip.c.
References ast_copy_string(), ast_exists_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), sip_refer::attendedtransfer, sip_pvt::context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, ast_channel::macrocontext, option_debug, sip_pvt::owner, pbx_builtin_getvar_helper(), sip_pvt::refer, sip_refer::refer_to, sip_refer::refer_to_context, sip_refer::refer_to_domain, sip_refer::refer_to_urioption, sip_refer::referred_by, sip_refer::referred_by_name, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, S_OR, and sip_debug_test_pvt().
Referenced by handle_request_refer().
09241 { 09242 09243 const char *p_referred_by = NULL; 09244 char *h_refer_to = NULL; 09245 char *h_referred_by = NULL; 09246 char *refer_to; 09247 const char *p_refer_to; 09248 char *referred_by_uri = NULL; 09249 char *ptr; 09250 struct sip_request *req = NULL; 09251 const char *transfer_context = NULL; 09252 struct sip_refer *referdata; 09253 09254 09255 req = outgoing_req; 09256 referdata = transferer->refer; 09257 09258 if (!req) 09259 req = &transferer->initreq; 09260 09261 p_refer_to = get_header(req, "Refer-To"); 09262 if (ast_strlen_zero(p_refer_to)) { 09263 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 09264 return -2; /* Syntax error */ 09265 } 09266 h_refer_to = ast_strdupa(p_refer_to); 09267 refer_to = get_in_brackets(h_refer_to); 09268 if (pedanticsipchecking) 09269 ast_uri_decode(refer_to); 09270 09271 if (strncasecmp(refer_to, "sip:", 4)) { 09272 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 09273 return -3; 09274 } 09275 refer_to += 4; /* Skip sip: */ 09276 09277 /* Get referred by header if it exists */ 09278 p_referred_by = get_header(req, "Referred-By"); 09279 if (!ast_strlen_zero(p_referred_by)) { 09280 char *lessthan; 09281 h_referred_by = ast_strdupa(p_referred_by); 09282 if (pedanticsipchecking) 09283 ast_uri_decode(h_referred_by); 09284 09285 /* Store referrer's caller ID name */ 09286 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 09287 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 09288 *(lessthan - 1) = '\0'; /* Space */ 09289 } 09290 09291 referred_by_uri = get_in_brackets(h_referred_by); 09292 if(strncasecmp(referred_by_uri, "sip:", 4)) { 09293 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 09294 referred_by_uri = (char *) NULL; 09295 } else { 09296 referred_by_uri += 4; /* Skip sip: */ 09297 } 09298 } 09299 09300 /* Check for arguments in the refer_to header */ 09301 if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */ 09302 *ptr++ = '\0'; 09303 if (!strncasecmp(ptr, "REPLACES=", 9)) { 09304 char *to = NULL, *from = NULL; 09305 09306 /* This is an attended transfer */ 09307 referdata->attendedtransfer = 1; 09308 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 09309 ast_uri_decode(referdata->replaces_callid); 09310 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 09311 *ptr++ = '\0'; 09312 } 09313 09314 if (ptr) { 09315 /* Find the different tags before we destroy the string */ 09316 to = strcasestr(ptr, "to-tag="); 09317 from = strcasestr(ptr, "from-tag="); 09318 } 09319 09320 /* Grab the to header */ 09321 if (to) { 09322 ptr = to + 7; 09323 if ((to = strchr(ptr, '&'))) 09324 *to = '\0'; 09325 if ((to = strchr(ptr, ';'))) 09326 *to = '\0'; 09327 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 09328 } 09329 09330 if (from) { 09331 ptr = from + 9; 09332 if ((to = strchr(ptr, '&'))) 09333 *to = '\0'; 09334 if ((to = strchr(ptr, ';'))) 09335 *to = '\0'; 09336 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 09337 } 09338 09339 if (option_debug > 1) { 09340 if (!pedanticsipchecking) 09341 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 09342 else 09343 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>" ); 09344 } 09345 } 09346 } 09347 09348 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 09349 char *urioption = NULL, *domain; 09350 *ptr++ = '\0'; 09351 09352 if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */ 09353 *urioption++ = '\0'; 09354 09355 domain = ptr; 09356 if ((ptr = strchr(domain, ':'))) /* Remove :port */ 09357 *ptr = '\0'; 09358 09359 /* Save the domain for the dial plan */ 09360 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 09361 if (urioption) 09362 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 09363 } 09364 09365 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 09366 *ptr = '\0'; 09367 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 09368 09369 if (referred_by_uri) { 09370 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 09371 *ptr = '\0'; 09372 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 09373 } else { 09374 referdata->referred_by[0] = '\0'; 09375 } 09376 09377 /* Determine transfer context */ 09378 if (transferer->owner) /* Mimic behaviour in res_features.c */ 09379 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 09380 09381 /* By default, use the context in the channel sending the REFER */ 09382 if (ast_strlen_zero(transfer_context)) { 09383 transfer_context = S_OR(transferer->owner->macrocontext, 09384 S_OR(transferer->context, default_context)); 09385 } 09386 09387 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 09388 09389 /* Either an existing extension or the parking extension */ 09390 if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 09391 if (sip_debug_test_pvt(transferer)) { 09392 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 09393 } 09394 /* We are ready to transfer to the extension */ 09395 return 0; 09396 } 09397 if (sip_debug_test_pvt(transferer)) 09398 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 09399 09400 /* Failure, we can't find this extension */ 09401 return -1; 09402 }
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 9565 of file chan_sip.c.
References ast_copy_string(), and AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
09566 { 09567 char *start; 09568 char *end; 09569 09570 start = strchr(input,':'); 09571 if (!start) { 09572 output[0] = '\0'; 09573 return 0; 09574 } 09575 start++; 09576 09577 /* we found "number" */ 09578 ast_copy_string(output,start,maxlen); 09579 output[maxlen-1] = '\0'; 09580 09581 end = strchr(output,'@'); 09582 if (end) 09583 *end = '\0'; 09584 else 09585 output[0] = '\0'; 09586 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 09587 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 09588 09589 return 0; 09590 }
static const char * get_sdp | ( | struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get a line from an SDP message body.
Definition at line 4294 of file chan_sip.c.
References get_sdp_iterate().
04295 { 04296 int dummy = 0; 04297 04298 return get_sdp_iterate(&dummy, req, name); 04299 }
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 4280 of file chan_sip.c.
References get_body_by_line(), len(), and sip_request::line.
04281 { 04282 int len = strlen(name); 04283 04284 while (*start < req->sdp_end) { 04285 const char *r = get_body_by_line(req->line[(*start)++], name, len); 04286 if (r[0] != '\0') 04287 return r; 04288 } 04289 04290 return ""; 04291 }
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 9178 of file chan_sip.c.
References ast_channel_trylock, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, sip_pvt::callid, DEADLOCK_AVOIDANCE, sip_pvt::flags, iflist, iflock, sip_pvt::lock, LOG_DEBUG, match(), sip_pvt::next, option_debug, sip_pvt::owner, SIP_PAGE2_OUTGOING_CALL, sip_pvt::tag, and sip_pvt::theirtag.
Referenced by handle_request_invite(), and local_attended_transfer().
09179 { 09180 struct sip_pvt *sip_pvt_ptr; 09181 09182 ast_mutex_lock(&iflock); 09183 09184 if (option_debug > 3 && totag) 09185 ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 09186 09187 /* Search interfaces and find the match */ 09188 for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 09189 if (!strcmp(sip_pvt_ptr->callid, callid)) { 09190 int match = 1; 09191 09192 /* Go ahead and lock it (and its owner) before returning */ 09193 ast_mutex_lock(&sip_pvt_ptr->lock); 09194 09195 /* Check if tags match. If not, this is not the call we want 09196 (With a forking SIP proxy, several call legs share the 09197 call id, but have different tags) 09198 */ 09199 if (pedanticsipchecking) { 09200 const char *pvt_fromtag, *pvt_totag; 09201 09202 if (ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_OUTGOING_CALL)) { 09203 /* Outgoing call tags : from is "our", to is "their" */ 09204 pvt_fromtag = sip_pvt_ptr->tag ; 09205 pvt_totag = sip_pvt_ptr->theirtag ; 09206 } else { 09207 /* Incoming call tags : from is "their", to is "our" */ 09208 pvt_fromtag = sip_pvt_ptr->theirtag ; 09209 pvt_totag = sip_pvt_ptr->tag ; 09210 } 09211 if (ast_strlen_zero(fromtag) || strcmp(fromtag, pvt_fromtag) || (!ast_strlen_zero(totag) && strcmp(totag, pvt_totag))) 09212 match = 0; 09213 } 09214 09215 if (!match) { 09216 ast_mutex_unlock(&sip_pvt_ptr->lock); 09217 continue; 09218 } 09219 09220 if (option_debug > 3 && totag) 09221 ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n", 09222 ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_OUTGOING_CALL) ? "OUTGOING": "INCOMING", 09223 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 09224 09225 /* deadlock avoidance... */ 09226 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 09227 DEADLOCK_AVOIDANCE(&sip_pvt_ptr->lock); 09228 } 09229 break; 09230 } 09231 } 09232 ast_mutex_unlock(&iflock); 09233 if (option_debug > 3 && !sip_pvt_ptr) 09234 ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 09235 return sip_pvt_ptr; 09236 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 13638 of file chan_sip.c.
References ast_copy_string(), and get_header().
Referenced by find_call(), handle_request(), handle_request_subscribe(), and handle_response().
13639 { 13640 const char *thetag; 13641 13642 if (!tagbuf) 13643 return NULL; 13644 tagbuf[0] = '\0'; /* reset the buffer */ 13645 thetag = get_header(req, header); 13646 thetag = strcasestr(thetag, ";tag="); 13647 if (thetag) { 13648 thetag += 5; 13649 ast_copy_string(tagbuf, thetag, tagbufsize); 13650 return strsep(&tagbuf, ";"); 13651 } 13652 return NULL; 13653 }
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 16893 of file chan_sip.c.
References ast_clear_flag, ast_copy_string(), ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), ast_channel::flags, ast_variable::lineno, ast_variable::name, ast_channel::next, set_insecure_flags(), SIP_CAN_REINVITE, SIP_CAN_REINVITE_NAT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_G726_NONSTANDARD, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, SIP_NAT_ROUTE, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_BUGGY_MWI, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_UDPTL_DESTINATION, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NO, SIP_PROG_INBAND_YES, SIP_PROMISCREDIR, SIP_REINVITE, SIP_REINVITE_UPDATE, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USECLIENTCODE, and ast_variable::value.
Referenced by build_peer(), and build_user().
16894 { 16895 int res = 1; 16896 16897 if (!strcasecmp(v->name, "trustrpid")) { 16898 ast_set_flag(&mask[0], SIP_TRUSTRPID); 16899 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 16900 } else if (!strcasecmp(v->name, "sendrpid")) { 16901 ast_set_flag(&mask[0], SIP_SENDRPID); 16902 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 16903 } else if (!strcasecmp(v->name, "g726nonstandard")) { 16904 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 16905 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 16906 } else if (!strcasecmp(v->name, "useclientcode")) { 16907 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 16908 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 16909 } else if (!strcasecmp(v->name, "dtmfmode")) { 16910 ast_set_flag(&mask[0], SIP_DTMF); 16911 ast_clear_flag(&flags[0], SIP_DTMF); 16912 if (!strcasecmp(v->value, "inband")) 16913 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 16914 else if (!strcasecmp(v->value, "rfc2833")) 16915 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 16916 else if (!strcasecmp(v->value, "info")) 16917 ast_set_flag(&flags[0], SIP_DTMF_INFO); 16918 else if (!strcasecmp(v->value, "auto")) 16919 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 16920 else { 16921 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 16922 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 16923 } 16924 } else if (!strcasecmp(v->name, "nat")) { 16925 ast_set_flag(&mask[0], SIP_NAT); 16926 ast_clear_flag(&flags[0], SIP_NAT); 16927 if (!strcasecmp(v->value, "never")) 16928 ast_set_flag(&flags[0], SIP_NAT_NEVER); 16929 else if (!strcasecmp(v->value, "route")) 16930 ast_set_flag(&flags[0], SIP_NAT_ROUTE); 16931 else if (ast_true(v->value)) 16932 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 16933 else 16934 ast_set_flag(&flags[0], SIP_NAT_RFC3581); 16935 } else if (!strcasecmp(v->name, "canreinvite")) { 16936 ast_set_flag(&mask[0], SIP_REINVITE); 16937 ast_clear_flag(&flags[0], SIP_REINVITE); 16938 if(ast_true(v->value)) { 16939 ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT); 16940 } else if (!ast_false(v->value)) { 16941 char buf[64]; 16942 char *word, *next = buf; 16943 16944 ast_copy_string(buf, v->value, sizeof(buf)); 16945 while ((word = strsep(&next, ","))) { 16946 if(!strcasecmp(word, "update")) { 16947 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 16948 } else if(!strcasecmp(word, "nonat")) { 16949 ast_set_flag(&flags[0], SIP_CAN_REINVITE); 16950 ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT); 16951 } else { 16952 ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno); 16953 } 16954 } 16955 } 16956 } else if (!strcasecmp(v->name, "insecure")) { 16957 ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16958 ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16959 set_insecure_flags(flags, v->value, v->lineno); 16960 } else if (!strcasecmp(v->name, "progressinband")) { 16961 ast_set_flag(&mask[0], SIP_PROG_INBAND); 16962 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 16963 if (ast_true(v->value)) 16964 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 16965 else if (strcasecmp(v->value, "never")) 16966 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 16967 } else if (!strcasecmp(v->name, "promiscredir")) { 16968 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 16969 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 16970 } else if (!strcasecmp(v->name, "videosupport")) { 16971 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 16972 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 16973 } else if (!strcasecmp(v->name, "allowoverlap")) { 16974 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 16975 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 16976 } else if (!strcasecmp(v->name, "allowsubscribe")) { 16977 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 16978 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 16979 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 16980 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 16981 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 16982 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 16983 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 16984 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 16985 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 16986 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 16987 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 16988 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 16989 #endif 16990 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 16991 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 16992 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 16993 } else if (!strcasecmp(v->name, "buggymwi")) { 16994 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 16995 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 16996 } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { 16997 ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); 16998 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); 16999 } else 17000 res = 0; 17001 17002 return res; 17003 }
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 13823 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_masquerade(), ast_channel_unlock, ast_frfree, ast_hangup(), ast_log(), ast_mutex_unlock(), ast_quiet_chan(), ast_read(), ast_set_flag, ast_setstate(), ast_state2str(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, DEFAULT_TRANS_TIMEOUT, f, sip_pvt::flags, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, ast_channel::name, option_debug, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_call, SIP_DEFER_BYE_ON_TRANSFER, sip_scheddestroy(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), and XMIT_RELIABLE.
Referenced by handle_request_invite().
13824 { 13825 struct ast_frame *f; 13826 int earlyreplace = 0; 13827 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 13828 struct ast_channel *c = p->owner; /* Our incoming call */ 13829 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 13830 struct ast_channel *targetcall; /* The bridge to the take-over target */ 13831 13832 /* Check if we're in ring state */ 13833 if (replacecall->_state == AST_STATE_RING) 13834 earlyreplace = 1; 13835 13836 /* Check if we have a bridge */ 13837 if (!(targetcall = ast_bridged_channel(replacecall))) { 13838 /* We have no bridge */ 13839 if (!earlyreplace) { 13840 if (option_debug > 1) 13841 ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 13842 oneleggedreplace = 1; 13843 } 13844 } 13845 if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING) 13846 ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n"); 13847 13848 if (option_debug > 3) { 13849 if (targetcall) 13850 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); 13851 else 13852 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 13853 } 13854 13855 if (ignore) { 13856 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 13857 /* We should answer something here. If we are here, the 13858 call we are replacing exists, so an accepted 13859 can't harm */ 13860 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13861 /* Do something more clever here */ 13862 ast_channel_unlock(c); 13863 ast_mutex_unlock(&p->refer->refer_call->lock); 13864 return 1; 13865 } 13866 if (!c) { 13867 /* What to do if no channel ??? */ 13868 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 13869 transmit_response_reliable(p, "503 Service Unavailable", req); 13870 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 13871 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13872 ast_mutex_unlock(&p->refer->refer_call->lock); 13873 return 1; 13874 } 13875 append_history(p, "Xfer", "INVITE/Replace received"); 13876 /* We have three channels to play with 13877 channel c: New incoming call 13878 targetcall: Call from PBX to target 13879 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 13880 replacecall: The owner of the previous 13881 We need to masq C into refer_call to connect to 13882 targetcall; 13883 If we are talking to internal audio stream, target call is null. 13884 */ 13885 13886 /* Fake call progress */ 13887 transmit_response(p, "100 Trying", req); 13888 ast_setstate(c, AST_STATE_RING); 13889 13890 /* Masquerade the new call into the referred call to connect to target call 13891 Targetcall is not touched by the masq */ 13892 13893 /* Answer the incoming call and set channel to UP state */ 13894 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13895 13896 ast_setstate(c, AST_STATE_UP); 13897 13898 /* Stop music on hold and other generators */ 13899 ast_quiet_chan(replacecall); 13900 ast_quiet_chan(targetcall); 13901 if (option_debug > 3) 13902 ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 13903 /* Unlock clone, but not original (replacecall) */ 13904 if (!oneleggedreplace) 13905 ast_channel_unlock(c); 13906 13907 /* Unlock PVT */ 13908 ast_mutex_unlock(&p->refer->refer_call->lock); 13909 13910 /* Make sure that the masq does not free our PVT for the old call */ 13911 if (! earlyreplace && ! oneleggedreplace ) 13912 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 13913 13914 /* Prepare the masquerade - if this does not happen, we will be gone */ 13915 if(ast_channel_masquerade(replacecall, c)) 13916 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 13917 else if (option_debug > 3) 13918 ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 13919 13920 /* The masquerade will happen as soon as someone reads a frame from the channel */ 13921 13922 /* C should now be in place of replacecall */ 13923 /* ast_read needs to lock channel */ 13924 ast_channel_unlock(c); 13925 13926 if (earlyreplace || oneleggedreplace ) { 13927 /* Force the masq to happen */ 13928 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13929 ast_frfree(f); 13930 f = NULL; 13931 if (option_debug > 3) 13932 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from RING channel!\n"); 13933 } else { 13934 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from RING channel \n"); 13935 } 13936 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13937 if (!oneleggedreplace) 13938 ast_channel_unlock(replacecall); 13939 } else { /* Bridged call, UP channel */ 13940 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13941 /* Masq ok */ 13942 ast_frfree(f); 13943 f = NULL; 13944 if (option_debug > 2) 13945 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from channel! Masq done.\n"); 13946 } else { 13947 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from channel. Transfer failed\n"); 13948 } 13949 ast_channel_unlock(replacecall); 13950 } 13951 ast_mutex_unlock(&p->refer->refer_call->lock); 13952 13953 ast_setstate(c, AST_STATE_DOWN); 13954 if (option_debug > 3) { 13955 struct ast_channel *test; 13956 ast_log(LOG_DEBUG, "After transfer:----------------------------\n"); 13957 ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 13958 if (replacecall) 13959 ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 13960 if (p->owner) { 13961 ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 13962 test = ast_bridged_channel(p->owner); 13963 if (test) 13964 ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 13965 else 13966 ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n"); 13967 } else 13968 ast_log(LOG_DEBUG, " -- No channel yet \n"); 13969 ast_log(LOG_DEBUG, "End After transfer:----------------------------\n"); 13970 } 13971 13972 ast_channel_unlock(p->owner); /* Unlock new owner */ 13973 if (!oneleggedreplace) 13974 ast_mutex_unlock(&p->lock); /* Unlock SIP structure */ 13975 13976 /* The call should be down with no ast_channel, so hang it up */ 13977 c->tech_pvt = NULL; 13978 ast_hangup(c); 13979 return 0; 13980 }
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 15797 of file chan_sip.c.
References __sip_ack(), append_history, ast_inet_ntoa(), ast_log(), ast_set_flag, ast_skip_blanks(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), check_pendings(), debug, DEFAULT_TRANS_TIMEOUT, extract_uri(), FALSE, find_sdp(), FLAG_RESPONSE, sip_pvt::flags, get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), sip_request::header, sip_request::headers, cfsip_methods::id, sip_pvt::initreq, INV_TERMINATED, len(), LOG_DEBUG, LOG_ERROR, LOG_NOTICE, sip_request::method, 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, sip_pvt::theirtag, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), TRUE, and sip_pvt::useragent.
15798 { 15799 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 15800 relatively static */ 15801 const char *cmd; 15802 const char *cseq; 15803 const char *useragent; 15804 int seqno; 15805 int len; 15806 int ignore = FALSE; 15807 int respid; 15808 int res = 0; 15809 int debug = sip_debug_test_pvt(p); 15810 char *e; 15811 int error = 0; 15812 15813 /* Get Method and Cseq */ 15814 cseq = get_header(req, "Cseq"); 15815 cmd = req->header[0]; 15816 15817 /* Must have Cseq */ 15818 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 15819 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 15820 error = 1; 15821 } 15822 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 15823 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 15824 error = 1; 15825 } 15826 if (error) { 15827 if (!p->initreq.headers) /* New call */ 15828 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 15829 return -1; 15830 } 15831 /* Get the command XXX */ 15832 15833 cmd = req->rlPart1; 15834 e = req->rlPart2; 15835 15836 /* Save useragent of the client */ 15837 useragent = get_header(req, "User-Agent"); 15838 if (!ast_strlen_zero(useragent)) 15839 ast_string_field_set(p, useragent, useragent); 15840 15841 /* Find out SIP method for incoming request */ 15842 if (req->method == SIP_RESPONSE) { /* Response to our request */ 15843 /* Response to our request -- Do some sanity checks */ 15844 if (!p->initreq.headers) { 15845 if (option_debug) 15846 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 15847 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15848 return 0; 15849 } else if (p->ocseq && (p->ocseq < seqno) && (seqno != p->lastnoninvite)) { 15850 if (option_debug) 15851 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 15852 return -1; 15853 } else if (p->ocseq && (p->ocseq != seqno) && (seqno != p->lastnoninvite)) { 15854 /* ignore means "don't do anything with it" but still have to 15855 respond appropriately */ 15856 ignore = TRUE; 15857 ast_set_flag(req, SIP_PKT_IGNORE); 15858 ast_set_flag(req, SIP_PKT_IGNORE_RESP); 15859 append_history(p, "Ignore", "Ignoring this retransmit\n"); 15860 } else if (e) { 15861 e = ast_skip_blanks(e); 15862 if (sscanf(e, "%d %n", &respid, &len) != 1) { 15863 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 15864 } else { 15865 if (respid <= 0) { 15866 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 15867 return 0; 15868 } 15869 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 15870 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 15871 extract_uri(p, req); 15872 handle_response(p, respid, e + len, req, ignore, seqno); 15873 } 15874 } 15875 return 0; 15876 } 15877 15878 /* New SIP request coming in 15879 (could be new request in existing SIP dialog as well...) 15880 */ 15881 15882 p->method = req->method; /* Find out which SIP method they are using */ 15883 if (option_debug > 3) 15884 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 15885 15886 if (p->icseq && (p->icseq > seqno) ) { 15887 if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) { 15888 if (option_debug > 2) 15889 ast_log(LOG_DEBUG, "Got CANCEL or ACK on INVITE with transactions in between.\n"); 15890 } else { 15891 if (option_debug) 15892 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 15893 if (req->method != SIP_ACK) 15894 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 15895 return -1; 15896 } 15897 } else if (p->icseq && 15898 p->icseq == seqno && 15899 req->method != SIP_ACK && 15900 (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) { 15901 /* ignore means "don't do anything with it" but still have to 15902 respond appropriately. We do this if we receive a repeat of 15903 the last sequence number */ 15904 ignore = 2; 15905 ast_set_flag(req, SIP_PKT_IGNORE); 15906 ast_set_flag(req, SIP_PKT_IGNORE_REQ); 15907 if (option_debug > 2) 15908 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 15909 } 15910 15911 if (seqno >= p->icseq) 15912 /* Next should follow monotonically (but not necessarily 15913 incrementally -- thanks again to the genius authors of SIP -- 15914 increasing */ 15915 p->icseq = seqno; 15916 15917 /* Find their tag if we haven't got it */ 15918 if (ast_strlen_zero(p->theirtag)) { 15919 char tag[128]; 15920 15921 gettag(req, "From", tag, sizeof(tag)); 15922 ast_string_field_set(p, theirtag, tag); 15923 } 15924 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 15925 15926 if (pedanticsipchecking) { 15927 /* If this is a request packet without a from tag, it's not 15928 correct according to RFC 3261 */ 15929 /* Check if this a new request in a new dialog with a totag already attached to it, 15930 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 15931 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 15932 /* If this is a first request and it got a to-tag, it is not for us */ 15933 if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) { 15934 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 15935 /* Will cease to exist after ACK */ 15936 } else if (req->method != SIP_ACK) { 15937 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 15938 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15939 } 15940 return res; 15941 } 15942 } 15943 15944 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 15945 transmit_response(p, "400 Bad request", req); 15946 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15947 return -1; 15948 } 15949 15950 /* Handle various incoming SIP methods in requests */ 15951 switch (p->method) { 15952 case SIP_OPTIONS: 15953 res = handle_request_options(p, req); 15954 break; 15955 case SIP_INVITE: 15956 res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock); 15957 break; 15958 case SIP_REFER: 15959 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 15960 break; 15961 case SIP_CANCEL: 15962 res = handle_request_cancel(p, req); 15963 break; 15964 case SIP_BYE: 15965 res = handle_request_bye(p, req); 15966 break; 15967 case SIP_MESSAGE: 15968 res = handle_request_message(p, req); 15969 break; 15970 case SIP_SUBSCRIBE: 15971 res = handle_request_subscribe(p, req, sin, seqno, e); 15972 break; 15973 case SIP_REGISTER: 15974 res = handle_request_register(p, req, sin, e); 15975 break; 15976 case SIP_INFO: 15977 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15978 ast_verbose("Receiving INFO!\n"); 15979 if (!ignore) 15980 handle_request_info(p, req); 15981 else /* if ignoring, transmit response */ 15982 transmit_response(p, "200 OK", req); 15983 break; 15984 case SIP_NOTIFY: 15985 res = handle_request_notify(p, req, sin, seqno, e); 15986 break; 15987 case SIP_ACK: 15988 /* Make sure we don't ignore this */ 15989 if (seqno == p->pendinginvite) { 15990 p->invitestate = INV_TERMINATED; 15991 p->pendinginvite = 0; 15992 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 15993 if (find_sdp(req)) { 15994 if (process_sdp(p, req)) 15995 return -1; 15996 } 15997 check_pendings(p); 15998 } 15999 /* Got an ACK that we did not match. Ignore silently */ 16000 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 16001 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16002 break; 16003 default: 16004 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 16005 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 16006 cmd, ast_inet_ntoa(p->sa.sin_addr)); 16007 /* If this is some new method, and we don't have a call, destroy it now */ 16008 if (!p->initreq.headers) 16009 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16010 break; 16011 } 16012 return res; 16013 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 15358 of file chan_sip.c.
References __sip_pretend_ack(), append_history, ast_async_goto(), ast_bridged_channel(), ast_clear_flag, AST_CONTROL_UNHOLD, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_rtp_get_quality(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, check_via(), context, sip_pvt::context, copy_request(), DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, get_also_info(), get_header(), sip_pvt::initreq, INV_TERMINATED, sip_pvt::invitestate, LOG_DEBUG, LOG_NOTICE, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_pvt::recv, sip_pvt::refer, sip_refer::refer_to, sip_pvt::rtp, sip_alreadygone(), SIP_NO_HISTORY, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_IGNORE, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and sip_pvt::vrtp.
Referenced by handle_request().
15359 { 15360 struct ast_channel *c=NULL; 15361 int res; 15362 struct ast_channel *bridged_to; 15363 15364 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 15365 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 15366 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 15367 15368 __sip_pretend_ack(p); 15369 15370 p->invitestate = INV_TERMINATED; 15371 15372 copy_request(&p->initreq, req); 15373 check_via(p, req); 15374 sip_alreadygone(p); 15375 15376 /* Get RTCP quality before end of call */ 15377 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { 15378 char *audioqos, *videoqos; 15379 if (p->rtp) { 15380 audioqos = ast_rtp_get_quality(p->rtp, NULL); 15381 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 15382 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 15383 if (p->owner) 15384 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 15385 } 15386 if (p->vrtp) { 15387 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 15388 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 15389 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 15390 if (p->owner) 15391 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 15392 } 15393 } 15394 15395 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 15396 15397 if (!ast_strlen_zero(get_header(req, "Also"))) { 15398 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 15399 ast_inet_ntoa(p->recv.sin_addr)); 15400 if (ast_strlen_zero(p->context)) 15401 ast_string_field_set(p, context, default_context); 15402 res = get_also_info(p, req); 15403 if (!res) { 15404 c = p->owner; 15405 if (c) { 15406 bridged_to = ast_bridged_channel(c); 15407 if (bridged_to) { 15408 /* Don't actually hangup here... */ 15409 ast_queue_control(c, AST_CONTROL_UNHOLD); 15410 ast_async_goto(bridged_to, p->context, p->refer->refer_to,1); 15411 } else 15412 ast_queue_hangup(p->owner); 15413 } 15414 } else { 15415 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 15416 if (p->owner) 15417 ast_queue_hangup(p->owner); 15418 } 15419 } else if (p->owner) { 15420 ast_queue_hangup(p->owner); 15421 if (option_debug > 2) 15422 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n"); 15423 } else { 15424 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15425 if (option_debug > 2) 15426 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n"); 15427 } 15428 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15429 transmit_response(p, "200 OK", req); 15430 15431 return 1; 15432 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 15252 of file chan_sip.c.
References __sip_pretend_ack(), ast_log(), ast_queue_hangup(), AST_STATE_UP, ast_test_flag, check_via(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, INV_CANCELLED, INV_TERMINATED, sip_pvt::invitestate, LOG_DEBUG, option_debug, sip_dual::req, sip_alreadygone(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and update_call_counter().
Referenced by handle_request().
15253 { 15254 15255 check_via(p, req); 15256 sip_alreadygone(p); 15257 15258 /* At this point, we could have cancelled the invite at the same time 15259 as the other side sends a CANCEL. Our final reply with error code 15260 might not have been received by the other side before the CANCEL 15261 was sent, so let's just give up retransmissions and waiting for 15262 ACK on our error code. The call is hanging up any way. */ 15263 if (p->invitestate == INV_TERMINATED) 15264 __sip_pretend_ack(p); 15265 else 15266 p->invitestate = INV_CANCELLED; 15267 15268 if (p->owner && p->owner->_state == AST_STATE_UP) { 15269 /* This call is up, cancel is ignored, we need a bye */ 15270 transmit_response(p, "200 OK", req); 15271 if (option_debug) 15272 ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n"); 15273 return 0; 15274 } 15275 15276 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 15277 update_call_counter(p, DEC_CALL_LIMIT); 15278 15279 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 15280 if (p->owner) 15281 ast_queue_hangup(p->owner); 15282 else 15283 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15284 if (p->initreq.len > 0) { 15285 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 15286 transmit_response(p, "200 OK", req); 15287 return 1; 15288 } else { 15289 transmit_response(p, "481 Call Leg Does Not Exist", req); 15290 return 0; 15291 } 15292 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 11404 of file chan_sip.c.
References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, ast_copy_string(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), ast_queue_control(), ast_queue_frame(), ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_pvt::callid, ast_channel::cdr, DEFAULT_TRANS_TIMEOUT, sip_history::event, f, sip_pvt::flags, get_body(), get_header(), sip_pvt::owner, sip_scheddestroy(), SIP_USECLIENTCODE, sipdebug, and transmit_response().
Referenced by handle_request().
11405 { 11406 char buf[1024]; 11407 unsigned int event; 11408 const char *c = get_header(req, "Content-Type"); 11409 11410 /* Need to check the media/type */ 11411 if (!strcasecmp(c, "application/dtmf-relay") || 11412 !strcasecmp(c, "application/DTMF") || 11413 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 11414 unsigned int duration = 0; 11415 11416 /* Try getting the "signal=" part */ 11417 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 11418 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 11419 transmit_response(p, "200 OK", req); /* Should return error */ 11420 return; 11421 } else { 11422 ast_copy_string(buf, c, sizeof(buf)); 11423 } 11424 11425 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 11426 duration = atoi(c); 11427 if (!duration) 11428 duration = 100; /* 100 ms */ 11429 11430 if (!p->owner) { /* not a PBX call */ 11431 transmit_response(p, "481 Call leg/transaction does not exist", req); 11432 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11433 return; 11434 } 11435 11436 if (ast_strlen_zero(buf)) { 11437 transmit_response(p, "200 OK", req); 11438 return; 11439 } 11440 11441 if (buf[0] == '*') 11442 event = 10; 11443 else if (buf[0] == '#') 11444 event = 11; 11445 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 11446 event = 12 + buf[0] - 'A'; 11447 else 11448 event = atoi(buf); 11449 if (event == 16) { 11450 /* send a FLASH event */ 11451 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 11452 ast_queue_frame(p->owner, &f); 11453 if (sipdebug) 11454 ast_verbose("* DTMF-relay event received: FLASH\n"); 11455 } else { 11456 /* send a DTMF event */ 11457 struct ast_frame f = { AST_FRAME_DTMF, }; 11458 if (event < 10) { 11459 f.subclass = '0' + event; 11460 } else if (event < 11) { 11461 f.subclass = '*'; 11462 } else if (event < 12) { 11463 f.subclass = '#'; 11464 } else if (event < 16) { 11465 f.subclass = 'A' + (event - 12); 11466 } 11467 f.len = duration; 11468 ast_queue_frame(p->owner, &f); 11469 if (sipdebug) 11470 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 11471 } 11472 transmit_response(p, "200 OK", req); 11473 return; 11474 } else if (!strcasecmp(c, "application/media_control+xml")) { 11475 /* Eh, we'll just assume it's a fast picture update for now */ 11476 if (p->owner) 11477 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 11478 transmit_response(p, "200 OK", req); 11479 return; 11480 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 11481 /* Client code (from SNOM phone) */ 11482 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 11483 if (p->owner && p->owner->cdr) 11484 ast_cdr_setuserfield(p->owner, c); 11485 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 11486 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 11487 transmit_response(p, "200 OK", req); 11488 } else { 11489 transmit_response(p, "403 Unauthorized", req); 11490 } 11491 return; 11492 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 11493 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 11494 transmit_response(p, "200 OK", req); 11495 return; 11496 } 11497 11498 /* Other type of INFO message, not really understood by Asterisk */ 11499 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 11500 11501 /* Nothing in the header is interesting, now check if content-length is 0 */ 11502 if (!strcasecmp(get_header(req, "Content-Length"), "0")) { 11503 transmit_response(p, "200 OK", req); 11504 return; 11505 } /* else ... there issomething in the message body, do something with it if you need to */ 11506 11507 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 11508 transmit_response(p, "415 Unsupported media type", req); 11509 return; 11510 }
static int handle_request_invite | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | debug, | |||
int | seqno, | |||
struct sockaddr_in * | sin, | |||
int * | recount, | |||
char * | e, | |||
int * | nounlock | |||
) | [static] |
Handle incoming INVITE request.
XXX: we should also check here does the other side supports t38 at all !!! XXX
Definition at line 14248 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_BUSY, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_pickup_call(), ast_pickup_ext(), ast_queue_control(), ast_queue_frame(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_set_flag, ast_setstate(), ast_skip_blanks(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), build_route(), ast_channel::call_forward, sip_pvt::callid, sip_pvt::capability, change_hold_state(), check_user(), check_via(), context, sip_pvt::context, copy_request(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, exten, sip_pvt::exten, extract_uri(), FALSE, find_sdp(), sip_pvt::flags, get_destination(), get_header(), get_rdnis(), get_sip_pvt_byid_locked(), handle_invite_replaces(), ast_channel::hangupcause, sip_request::headers, INC_CALL_LIMIT, sip_pvt::initreq, INV_COMPLETED, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::jointcapability, sip_pvt::lastinvite, sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, make_our_tag(), ast_channel::name, option_debug, sip_pvt::owner, parse_ok_contact(), parse_sip_options(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_request::rlPart2, sip_pvt::rtp, S_OR, sip_alreadygone(), sip_cancel_destroy(), SIP_DTMF, SIP_DTMF_RFC2833, sip_handle_t38_reinvite(), SIP_INVITE, sip_new(), SIP_NO_HISTORY, SIP_OPT_REPLACES, SIP_OUTGOING, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PKT_IGNORE, sip_refer_allocate(), sip_scheddestroy(), sip_tech, sip_tech_info, sip_uri_cmp(), sipdebug, sip_pvt::sipoptions, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_PEER_REINVITE, sip_pvt::tag, ast_channel::tech, ast_channel::tech_pvt, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, sip_pvt::udptl, update_call_counter(), sip_pvt::username, XMIT_CRITICAL, XMIT_RELIABLE, and XMIT_UNRELIABLE.
Referenced by handle_request().
14249 { 14250 int res = 1; 14251 int gotdest; 14252 const char *p_replaces; 14253 char *replace_id = NULL; 14254 const char *required; 14255 unsigned int required_profile = 0; 14256 struct ast_channel *c = NULL; /* New channel */ 14257 int reinvite = 0; 14258 14259 /* Find out what they support */ 14260 if (!p->sipoptions) { 14261 const char *supported = get_header(req, "Supported"); 14262 if (!ast_strlen_zero(supported)) 14263 parse_sip_options(p, supported); 14264 } 14265 14266 /* Find out what they require */ 14267 required = get_header(req, "Require"); 14268 if (!ast_strlen_zero(required)) { 14269 required_profile = parse_sip_options(NULL, required); 14270 if (required_profile && required_profile != SIP_OPT_REPLACES) { 14271 /* At this point we only support REPLACES */ 14272 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 14273 ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required); 14274 p->invitestate = INV_COMPLETED; 14275 if (!p->lastinvite) 14276 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14277 return -1; 14278 } 14279 } 14280 14281 /* Check if this is a loop */ 14282 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 14283 /* This is a call to ourself. Send ourselves an error code and stop 14284 processing immediately, as SIP really has no good mechanism for 14285 being able to call yourself */ 14286 /* If pedantic is on, we need to check the tags. If they're different, this is 14287 in fact a forked call through a SIP proxy somewhere. */ 14288 int different; 14289 if (pedanticsipchecking) 14290 different = sip_uri_cmp(p->initreq.rlPart2, req->rlPart2); 14291 else 14292 different = strcmp(p->initreq.rlPart2, req->rlPart2); 14293 if (!different) { 14294 transmit_response(p, "482 Loop Detected", req); 14295 p->invitestate = INV_COMPLETED; 14296 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14297 return 0; 14298 } else { 14299 /* This is a spiral. What we need to do is to just change the outgoing INVITE 14300 * so that it now routes to the new Request URI. Since we created the INVITE ourselves 14301 * that should be all we need to do. 14302 */ 14303 char *uri = ast_strdupa(req->rlPart2); 14304 char *at = strchr(uri, '@'); 14305 char *peerorhost; 14306 if (option_debug > 2) { 14307 ast_log(LOG_DEBUG, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", p->initreq.rlPart2, req->rlPart2); 14308 } 14309 if (at) { 14310 *at = '\0'; 14311 } 14312 /* Parse out "sip:" */ 14313 if ((peerorhost = strchr(uri, ':'))) { 14314 *peerorhost++ = '\0'; 14315 } 14316 ast_string_field_free(p, theirtag); 14317 /* Treat this as if there were a call forward instead... 14318 */ 14319 ast_string_field_set(p->owner, call_forward, peerorhost); 14320 ast_queue_control(p->owner, AST_CONTROL_BUSY); 14321 return 0; 14322 } 14323 } 14324 14325 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) { 14326 /* We already have a pending invite. Sorry. You are on hold. */ 14327 transmit_response_reliable(p, "491 Request Pending", req); 14328 if (option_debug) 14329 ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 14330 /* Don't destroy dialog here */ 14331 return 0; 14332 } 14333 14334 p_replaces = get_header(req, "Replaces"); 14335 if (!ast_strlen_zero(p_replaces)) { 14336 /* We have a replaces header */ 14337 char *ptr; 14338 char *fromtag = NULL; 14339 char *totag = NULL; 14340 char *start, *to; 14341 int error = 0; 14342 14343 if (p->owner) { 14344 if (option_debug > 2) 14345 ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 14346 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 14347 /* Do not destroy existing call */ 14348 return -1; 14349 } 14350 14351 if (sipdebug && option_debug > 2) 14352 ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 14353 /* Create a buffer we can manipulate */ 14354 replace_id = ast_strdupa(p_replaces); 14355 ast_uri_decode(replace_id); 14356 14357 if (!p->refer && !sip_refer_allocate(p)) { 14358 transmit_response_reliable(p, "500 Server Internal Error", req); 14359 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 14360 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14361 p->invitestate = INV_COMPLETED; 14362 return -1; 14363 } 14364 14365 /* Todo: (When we find phones that support this) 14366 if the replaces header contains ";early-only" 14367 we can only replace the call in early 14368 stage, not after it's up. 14369 14370 If it's not in early mode, 486 Busy. 14371 */ 14372 14373 /* Skip leading whitespace */ 14374 replace_id = ast_skip_blanks(replace_id); 14375 14376 start = replace_id; 14377 while ( (ptr = strsep(&start, ";")) ) { 14378 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 14379 if ( (to = strcasestr(ptr, "to-tag=") ) ) 14380 totag = to + 7; /* skip the keyword */ 14381 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 14382 fromtag = to + 9; /* skip the keyword */ 14383 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 14384 } 14385 } 14386 14387 if (sipdebug && option_debug > 3) 14388 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>"); 14389 14390 14391 /* Try to find call that we are replacing 14392 If we have a Replaces header, we need to cancel that call if we succeed with this call 14393 */ 14394 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 14395 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 14396 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req); 14397 error = 1; 14398 } 14399 14400 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 14401 14402 /* The matched call is the call from the transferer to Asterisk . 14403 We want to bridge the bridged part of the call to the 14404 incoming invite, thus taking over the refered call */ 14405 14406 if (p->refer->refer_call == p) { 14407 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 14408 p->refer->refer_call = NULL; 14409 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 14410 error = 1; 14411 } 14412 14413 if (!error && !p->refer->refer_call->owner) { 14414 /* Oops, someting wrong anyway, no owner, no call */ 14415 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 14416 /* Check for better return code */ 14417 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req); 14418 error = 1; 14419 } 14420 14421 if (!error && p->refer->refer_call->owner->_state != AST_STATE_RINGING && p->refer->refer_call->owner->_state != AST_STATE_RING && p->refer->refer_call->owner->_state != AST_STATE_UP ) { 14422 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 14423 transmit_response_reliable(p, "603 Declined (Replaces)", req); 14424 error = 1; 14425 } 14426 14427 if (error) { /* Give up this dialog */ 14428 append_history(p, "Xfer", "INVITE/Replace Failed."); 14429 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14430 ast_mutex_unlock(&p->lock); 14431 if (p->refer->refer_call) { 14432 ast_mutex_unlock(&p->refer->refer_call->lock); 14433 if (p->refer->refer_call->owner) { 14434 ast_channel_unlock(p->refer->refer_call->owner); 14435 } 14436 } 14437 p->invitestate = INV_COMPLETED; 14438 return -1; 14439 } 14440 } 14441 14442 14443 /* Check if this is an INVITE that sets up a new dialog or 14444 a re-invite in an existing dialog */ 14445 14446 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14447 int newcall = (p->initreq.headers ? TRUE : FALSE); 14448 14449 if (sip_cancel_destroy(p)) 14450 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 14451 /* This also counts as a pending invite */ 14452 p->pendinginvite = seqno; 14453 check_via(p, req); 14454 14455 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 14456 if (!p->owner) { /* Not a re-invite */ 14457 if (debug) 14458 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 14459 if (newcall) 14460 append_history(p, "Invite", "New call: %s", p->callid); 14461 parse_ok_contact(p, req); 14462 } else { /* Re-invite on existing call */ 14463 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 14464 /* Handle SDP here if we already have an owner */ 14465 if (find_sdp(req)) { 14466 if (process_sdp(p, req)) { 14467 transmit_response_reliable(p, "488 Not acceptable here", req); 14468 if (!p->lastinvite) 14469 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14470 return -1; 14471 } 14472 } else { 14473 p->jointcapability = p->capability; 14474 if (option_debug > 2) 14475 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 14476 /* Some devices signal they want to be put off hold by sending a re-invite 14477 *without* an SDP, which is supposed to mean "Go back to your state" 14478 and since they put os on remote hold, we go back to off hold */ 14479 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 14480 change_hold_state(p, req, FALSE, 0); 14481 } 14482 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */ 14483 append_history(p, "ReInv", "Re-invite received"); 14484 } 14485 } else if (debug) 14486 ast_verbose("Ignoring this INVITE request\n"); 14487 14488 14489 if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) { 14490 /* This is a new invite */ 14491 /* Handle authentication if this is our first invite */ 14492 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 14493 if (res == AUTH_CHALLENGE_SENT) { 14494 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 14495 return 0; 14496 } 14497 if (res < 0) { /* Something failed in authentication */ 14498 if (res == AUTH_FAKE_AUTH) { 14499 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 14500 transmit_fake_auth_response(p, req, 1); 14501 } else { 14502 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 14503 transmit_response_reliable(p, "403 Forbidden", req); 14504 } 14505 p->invitestate = INV_COMPLETED; 14506 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14507 ast_string_field_free(p, theirtag); 14508 return 0; 14509 } 14510 14511 /* We have a succesful authentication, process the SDP portion if there is one */ 14512 if (find_sdp(req)) { 14513 if (process_sdp(p, req)) { 14514 /* Unacceptable codecs */ 14515 transmit_response_reliable(p, "488 Not acceptable here", req); 14516 p->invitestate = INV_COMPLETED; 14517 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14518 if (option_debug) 14519 ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); 14520 return -1; 14521 } 14522 } else { /* No SDP in invite, call control session */ 14523 p->jointcapability = p->capability; 14524 if (option_debug > 1) 14525 ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n"); 14526 } 14527 14528 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 14529 /* This seems redundant ... see !p-owner above */ 14530 if (p->owner) 14531 ast_queue_frame(p->owner, &ast_null_frame); 14532 14533 14534 /* Initialize the context if it hasn't been already */ 14535 if (ast_strlen_zero(p->context)) 14536 ast_string_field_set(p, context, default_context); 14537 14538 14539 /* Check number of concurrent calls -vs- incoming limit HERE */ 14540 if (option_debug) 14541 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 14542 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 14543 if (res < 0) { 14544 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 14545 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 14546 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14547 p->invitestate = INV_COMPLETED; 14548 } 14549 return 0; 14550 } 14551 gotdest = get_destination(p, NULL); /* Get destination right away */ 14552 get_rdnis(p, NULL); /* Get redirect information */ 14553 extract_uri(p, req); /* Get the Contact URI */ 14554 build_contact(p); /* Build our contact header */ 14555 14556 if (p->rtp) { 14557 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 14558 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 14559 } 14560 14561 if (!replace_id && gotdest) { /* No matching extension found */ 14562 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 14563 transmit_response_reliable(p, "484 Address Incomplete", req); 14564 else { 14565 char *decoded_exten = ast_strdupa(p->exten); 14566 14567 transmit_response_reliable(p, "404 Not Found", req); 14568 ast_uri_decode(decoded_exten); 14569 ast_log(LOG_NOTICE, "Call from '%s' to extension" 14570 " '%s' rejected because extension not found.\n", 14571 S_OR(p->username, p->peername), decoded_exten); 14572 } 14573 p->invitestate = INV_COMPLETED; 14574 update_call_counter(p, DEC_CALL_LIMIT); 14575 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14576 return 0; 14577 } else { 14578 /* If no extension was specified, use the s one */ 14579 /* Basically for calling to IP/Host name only */ 14580 if (ast_strlen_zero(p->exten)) 14581 ast_string_field_set(p, exten, "s"); 14582 /* Initialize our tag */ 14583 14584 make_our_tag(p->tag, sizeof(p->tag)); 14585 /* First invitation - create the channel */ 14586 c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL)); 14587 *recount = 1; 14588 14589 /* Save Record-Route for any later requests we make on this dialogue */ 14590 build_route(p, req, 0); 14591 14592 if (c) { 14593 /* Pre-lock the call */ 14594 ast_channel_lock(c); 14595 } 14596 } 14597 } else { 14598 if (option_debug > 1 && sipdebug) { 14599 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 14600 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 14601 else 14602 ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 14603 } 14604 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 14605 reinvite = 1; 14606 c = p->owner; 14607 } 14608 14609 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 14610 p->lastinvite = seqno; 14611 14612 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 14613 /* Go and take over the target call */ 14614 if (sipdebug && option_debug > 3) 14615 ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid); 14616 return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin); 14617 } 14618 14619 14620 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 14621 switch(c->_state) { 14622 case AST_STATE_DOWN: 14623 if (option_debug > 1) 14624 ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name); 14625 transmit_response(p, "100 Trying", req); 14626 p->invitestate = INV_PROCEEDING; 14627 ast_setstate(c, AST_STATE_RING); 14628 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 14629 enum ast_pbx_result res; 14630 14631 res = ast_pbx_start(c); 14632 14633 switch(res) { 14634 case AST_PBX_FAILED: 14635 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 14636 p->invitestate = INV_COMPLETED; 14637 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14638 transmit_response(p, "503 Unavailable", req); 14639 else 14640 transmit_response_reliable(p, "503 Unavailable", req); 14641 break; 14642 case AST_PBX_CALL_LIMIT: 14643 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 14644 p->invitestate = INV_COMPLETED; 14645 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14646 transmit_response(p, "480 Temporarily Unavailable", req); 14647 else 14648 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 14649 break; 14650 case AST_PBX_SUCCESS: 14651 /* nothing to do */ 14652 break; 14653 } 14654 14655 if (res) { 14656 14657 /* Unlock locks so ast_hangup can do its magic */ 14658 ast_mutex_unlock(&c->lock); 14659 ast_mutex_unlock(&p->lock); 14660 ast_hangup(c); 14661 ast_mutex_lock(&p->lock); 14662 c = NULL; 14663 } 14664 } else { /* Pickup call in call group */ 14665 ast_channel_unlock(c); 14666 *nounlock = 1; 14667 if (ast_pickup_call(c)) { 14668 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 14669 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14670 transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */ 14671 else 14672 transmit_response_reliable(p, "503 Unavailable", req); 14673 sip_alreadygone(p); 14674 /* Unlock locks so ast_hangup can do its magic */ 14675 ast_mutex_unlock(&p->lock); 14676 c->hangupcause = AST_CAUSE_CALL_REJECTED; 14677 } else { 14678 ast_mutex_unlock(&p->lock); 14679 ast_setstate(c, AST_STATE_DOWN); 14680 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14681 } 14682 p->invitestate = INV_COMPLETED; 14683 ast_hangup(c); 14684 ast_mutex_lock(&p->lock); 14685 c = NULL; 14686 } 14687 break; 14688 case AST_STATE_RING: 14689 transmit_response(p, "100 Trying", req); 14690 p->invitestate = INV_PROCEEDING; 14691 break; 14692 case AST_STATE_RINGING: 14693 transmit_response(p, "180 Ringing", req); 14694 p->invitestate = INV_PROCEEDING; 14695 break; 14696 case AST_STATE_UP: 14697 if (option_debug > 1) 14698 ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); 14699 14700 transmit_response(p, "100 Trying", req); 14701 14702 if (p->t38.state == T38_PEER_REINVITE) { 14703 struct ast_channel *bridgepeer = NULL; 14704 struct sip_pvt *bridgepvt = NULL; 14705 14706 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14707 /* 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*/ 14708 /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */ 14709 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 14710 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14711 if (bridgepvt->t38.state == T38_DISABLED) { 14712 if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */ 14713 /* Send re-invite to the bridged channel */ 14714 sip_handle_t38_reinvite(bridgepeer, p, 1); 14715 } else { /* Something is wrong with peers udptl struct */ 14716 ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n"); 14717 ast_mutex_lock(&bridgepvt->lock); 14718 bridgepvt->t38.state = T38_DISABLED; 14719 ast_mutex_unlock(&bridgepvt->lock); 14720 if (option_debug > 1) 14721 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name); 14722 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14723 transmit_response(p, "488 Not acceptable here", req); 14724 else 14725 transmit_response_reliable(p, "488 Not acceptable here", req); 14726 14727 } 14728 } else { 14729 /* The other side is already setup for T.38 most likely so we need to acknowledge this too */ 14730 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 14731 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14732 p->t38.state = T38_ENABLED; 14733 if (option_debug) 14734 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14735 } 14736 } else { 14737 /* Other side is not a SIP channel */ 14738 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14739 transmit_response(p, "488 Not acceptable here", req); 14740 else 14741 transmit_response_reliable(p, "488 Not acceptable here", req); 14742 p->t38.state = T38_DISABLED; 14743 if (option_debug > 1) 14744 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14745 14746 if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */ 14747 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14748 } 14749 } else { 14750 /* we are not bridged in a call */ 14751 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 14752 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14753 p->t38.state = T38_ENABLED; 14754 if (option_debug) 14755 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14756 } 14757 } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */ 14758 int sendok = TRUE; 14759 14760 /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */ 14761 /* so handle it here (re-invite other party to RTP) */ 14762 struct ast_channel *bridgepeer = NULL; 14763 struct sip_pvt *bridgepvt = NULL; 14764 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14765 if ((bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) && !ast_check_hangup(bridgepeer)) { 14766 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14767 /* Does the bridged peer have T38 ? */ 14768 if (bridgepvt->t38.state == T38_ENABLED) { 14769 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 14770 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 14771 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14772 transmit_response(p, "488 Not Acceptable Here (unsupported)", req); 14773 else 14774 transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req); 14775 sendok = FALSE; 14776 } 14777 /* No bridged peer with T38 enabled*/ 14778 } 14779 } 14780 /* Respond to normal re-invite */ 14781 if (sendok) { 14782 /* If this is not a re-invite or something to ignore - it's critical */ 14783 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 14784 transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_CRITICAL))); 14785 } 14786 } 14787 p->invitestate = INV_TERMINATED; 14788 break; 14789 default: 14790 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 14791 transmit_response(p, "100 Trying", req); 14792 break; 14793 } 14794 } else { 14795 if (p && (p->autokillid == -1)) { 14796 const char *msg; 14797 14798 if (!p->jointcapability) 14799 msg = "488 Not Acceptable Here (codec error)"; 14800 else { 14801 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 14802 msg = "503 Unavailable"; 14803 } 14804 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14805 transmit_response(p, msg, req); 14806 else 14807 transmit_response_reliable(p, msg, req); 14808 p->invitestate = INV_COMPLETED; 14809 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14810 } 14811 } 14812 return res; 14813 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 15435 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().
15436 { 15437 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 15438 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15439 ast_verbose("Receiving message!\n"); 15440 receive_message(p, req); 15441 } else 15442 transmit_response(p, "202 Accepted", req); 15443 return 1; 15444 }
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 13656 of file chan_sip.c.
References ast_log(), ast_skip_blanks(), sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), get_msg_text(), sip_pvt::lastinvite, LOG_DEBUG, LOG_NOTICE, option_debug, sip_scheddestroy(), sipdebug, transmit_response(), and TRUE.
Referenced by handle_request().
13657 { 13658 /* This is mostly a skeleton for future improvements */ 13659 /* Mostly created to return proper answers on notifications on outbound REFER's */ 13660 int res = 0; 13661 const char *event = get_header(req, "Event"); 13662 char *eventid = NULL; 13663 char *sep; 13664 13665 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 13666 *sep++ = '\0'; 13667 eventid = sep; 13668 } 13669 13670 if (option_debug > 1 && sipdebug) 13671 ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event); 13672 13673 if (strcmp(event, "refer")) { 13674 /* We don't understand this event. */ 13675 /* Here's room to implement incoming voicemail notifications :-) */ 13676 transmit_response(p, "489 Bad event", req); 13677 res = -1; 13678 } else { 13679 /* Save nesting depth for now, since there might be other events we will 13680 support in the future */ 13681 13682 /* Handle REFER notifications */ 13683 13684 char buf[1024]; 13685 char *cmd, *code; 13686 int respcode; 13687 int success = TRUE; 13688 13689 /* EventID for each transfer... EventID is basically the REFER cseq 13690 13691 We are getting notifications on a call that we transfered 13692 We should hangup when we are getting a 200 OK in a sipfrag 13693 Check if we have an owner of this event */ 13694 13695 /* Check the content type */ 13696 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 13697 /* We need a sipfrag */ 13698 transmit_response(p, "400 Bad request", req); 13699 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13700 return -1; 13701 } 13702 13703 /* Get the text of the attachment */ 13704 if (get_msg_text(buf, sizeof(buf), req)) { 13705 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 13706 transmit_response(p, "400 Bad request", req); 13707 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13708 return -1; 13709 } 13710 13711 /* 13712 From the RFC... 13713 A minimal, but complete, implementation can respond with a single 13714 NOTIFY containing either the body: 13715 SIP/2.0 100 Trying 13716 13717 if the subscription is pending, the body: 13718 SIP/2.0 200 OK 13719 if the reference was successful, the body: 13720 SIP/2.0 503 Service Unavailable 13721 if the reference failed, or the body: 13722 SIP/2.0 603 Declined 13723 13724 if the REFER request was accepted before approval to follow the 13725 reference could be obtained and that approval was subsequently denied 13726 (see Section 2.4.7). 13727 13728 If there are several REFERs in the same dialog, we need to 13729 match the ID of the event header... 13730 */ 13731 if (option_debug > 2) 13732 ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 13733 cmd = ast_skip_blanks(buf); 13734 code = cmd; 13735 /* We are at SIP/2.0 */ 13736 while(*code && (*code > 32)) { /* Search white space */ 13737 code++; 13738 } 13739 *code++ = '\0'; 13740 code = ast_skip_blanks(code); 13741 sep = code; 13742 sep++; 13743 while(*sep && (*sep > 32)) { /* Search white space */ 13744 sep++; 13745 } 13746 *sep++ = '\0'; /* Response string */ 13747 respcode = atoi(code); 13748 switch (respcode) { 13749 case 100: /* Trying: */ 13750 case 101: /* dialog establishment */ 13751 /* Don't do anything yet */ 13752 break; 13753 case 183: /* Ringing: */ 13754 /* Don't do anything yet */ 13755 break; 13756 case 200: /* OK: The new call is up, hangup this call */ 13757 /* Hangup the call that we are replacing */ 13758 break; 13759 case 301: /* Moved permenantly */ 13760 case 302: /* Moved temporarily */ 13761 /* Do we get the header in the packet in this case? */ 13762 success = FALSE; 13763 break; 13764 case 503: /* Service Unavailable: The new call failed */ 13765 /* Cancel transfer, continue the call */ 13766 success = FALSE; 13767 break; 13768 case 603: /* Declined: Not accepted */ 13769 /* Cancel transfer, continue the current call */ 13770 success = FALSE; 13771 break; 13772 } 13773 if (!success) { 13774 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 13775 } 13776 13777 /* Confirm that we received this packet */ 13778 transmit_response(p, "200 OK", req); 13779 }; 13780 13781 if (!p->lastinvite) 13782 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13783 13784 return res; 13785 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming OPTIONS request.
Definition at line 13788 of file chan_sip.c.
References ast_shutting_down(), ast_string_field_set, ast_strlen_zero(), build_contact(), context, sip_pvt::context, DEFAULT_TRANS_TIMEOUT, get_destination(), sip_pvt::lastinvite, sip_scheddestroy(), and transmit_response_with_allow().
Referenced by handle_request().
13789 { 13790 int res; 13791 13792 13793 /* XXX Should we authenticate OPTIONS? XXX */ 13794 13795 if (p->lastinvite) { 13796 /* if this is a request in an active dialog, just confirm that the dialog exists. */ 13797 transmit_response_with_allow(p, "200 OK", req, 0); 13798 return 0; 13799 } 13800 13801 res = get_destination(p, req); 13802 build_contact(p); 13803 13804 if (ast_strlen_zero(p->context)) 13805 ast_string_field_set(p, context, default_context); 13806 13807 if (ast_shutting_down()) 13808 transmit_response_with_allow(p, "503 Unavailable", req, 0); 13809 else if (res < 0) 13810 transmit_response_with_allow(p, "404 Not Found", req, 0); 13811 else 13812 transmit_response_with_allow(p, "200 OK", req, 0); 13813 13814 /* Destroy if this OPTIONS was the opening request, but not if 13815 it's in the middle of a normal call flow. */ 13816 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13817 13818 return res; 13819 }
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 14981 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_pvt::callid, sip_dual::chan1, sip_dual::chan2, check_sip_domain(), context, sip_pvt::context, copy_request(), FALSE, sip_pvt::flags, get_refer_info(), ast_channel::hangupcause, local_attended_transfer(), sip_refer::localtransfer, LOG_DEBUG, ast_channel::name, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, REFER_200OK, REFER_FAILED, REFER_SENT, sip_refer::refer_to, sip_refer::refer_to_context, sip_refer::refer_to_domain, sip_refer::referred_by, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, sip_dual::req, sip_alreadygone(), SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_NEEDDESTROY, SIP_OUTGOING, sip_park(), SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_refer_allocate(), SIPBUFSIZE, sipdebug, sip_refer::status, TRANSFER_CLOSED, transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by handle_request().
14982 { 14983 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 14984 /* Chan2: Call between asterisk and transferee */ 14985 14986 int res = 0; 14987 14988 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14989 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"); 14990 14991 if (!p->owner) { 14992 /* This is a REFER outside of an existing SIP dialog */ 14993 /* We can't handle that, so decline it */ 14994 if (option_debug > 2) 14995 ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 14996 transmit_response(p, "603 Declined (No dialog)", req); 14997 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14998 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 14999 sip_alreadygone(p); 15000 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15001 } 15002 return 0; 15003 } 15004 15005 15006 /* Check if transfer is allowed from this device */ 15007 if (p->allowtransfer == TRANSFER_CLOSED ) { 15008 /* Transfer not allowed, decline */ 15009 transmit_response(p, "603 Declined (policy)", req); 15010 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 15011 /* Do not destroy SIP session */ 15012 return 0; 15013 } 15014 15015 if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 15016 /* Already have a pending REFER */ 15017 transmit_response(p, "491 Request pending", req); 15018 append_history(p, "Xfer", "Refer failed. Request pending."); 15019 return 0; 15020 } 15021 15022 /* Allocate memory for call transfer data */ 15023 if (!p->refer && !sip_refer_allocate(p)) { 15024 transmit_response(p, "500 Internal Server Error", req); 15025 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 15026 return -3; 15027 } 15028 15029 res = get_refer_info(p, req); /* Extract headers */ 15030 15031 p->refer->status = REFER_SENT; 15032 15033 if (res != 0) { 15034 switch (res) { 15035 case -2: /* Syntax error */ 15036 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 15037 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 15038 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 15039 ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 15040 break; 15041 case -3: 15042 transmit_response(p, "603 Declined (Non sip: uri)", req); 15043 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 15044 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 15045 ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n"); 15046 break; 15047 default: 15048 /* Refer-to extension not found, fake a failed transfer */ 15049 transmit_response(p, "202 Accepted", req); 15050 append_history(p, "Xfer", "Refer failed. Bad extension."); 15051 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 15052 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15053 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 15054 ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 15055 break; 15056 } 15057 return 0; 15058 } 15059 if (ast_strlen_zero(p->context)) 15060 ast_string_field_set(p, context, default_context); 15061 15062 /* If we do not support SIP domains, all transfers are local */ 15063 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 15064 p->refer->localtransfer = 1; 15065 if (sipdebug && option_debug > 2) 15066 ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 15067 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 15068 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 15069 p->refer->localtransfer = 1; 15070 } else if (sipdebug && option_debug > 2) 15071 ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 15072 15073 /* Is this a repeat of a current request? Ignore it */ 15074 /* Don't know what else to do right now. */ 15075 if (ignore) 15076 return res; 15077 15078 /* If this is a blind transfer, we have the following 15079 channels to work with: 15080 - chan1, chan2: The current call between transferer and transferee (2 channels) 15081 - target_channel: A new call from the transferee to the target (1 channel) 15082 We need to stay tuned to what happens in order to be able 15083 to bring back the call to the transferer */ 15084 15085 /* If this is a attended transfer, we should have all call legs within reach: 15086 - chan1, chan2: The call between the transferer and transferee (2 channels) 15087 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 15088 We want to bridge chan2 with targetcall_pvt! 15089 15090 The replaces call id in the refer message points 15091 to the call leg between Asterisk and the transferer. 15092 So we need to connect the target and the transferee channel 15093 and hangup the two other channels silently 15094 15095 If the target is non-local, the call ID could be on a remote 15096 machine and we need to send an INVITE with replaces to the 15097 target. We basically handle this as a blind transfer 15098 and let the sip_call function catch that we need replaces 15099 header in the INVITE. 15100 */ 15101 15102 15103 /* Get the transferer's channel */ 15104 current.chan1 = p->owner; 15105 15106 /* Find the other part of the bridge (2) - transferee */ 15107 current.chan2 = ast_bridged_channel(current.chan1); 15108 15109 if (sipdebug && option_debug > 2) 15110 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>"); 15111 15112 if (!current.chan2 && !p->refer->attendedtransfer) { 15113 /* No bridged channel, propably IVR or echo or similar... */ 15114 /* Guess we should masquerade or something here */ 15115 /* Until we figure it out, refuse transfer of such calls */ 15116 if (sipdebug && option_debug > 2) 15117 ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n"); 15118 p->refer->status = REFER_FAILED; 15119 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 15120 transmit_response(p, "603 Declined", req); 15121 return -1; 15122 } 15123 15124 if (current.chan2) { 15125 if (sipdebug && option_debug > 3) 15126 ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 15127 15128 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 15129 } 15130 15131 ast_set_flag(&p->flags[0], SIP_GOTREFER); 15132 15133 /* Attended transfer: Find all call legs and bridge transferee with target*/ 15134 if (p->refer->attendedtransfer) { 15135 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 15136 return res; /* We're done with the transfer */ 15137 /* Fall through for remote transfers that we did not find locally */ 15138 if (sipdebug && option_debug > 3) 15139 ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 15140 /* Fallthrough if we can't find the call leg internally */ 15141 } 15142 15143 15144 /* Parking a call */ 15145 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 15146 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 15147 *nounlock = 1; 15148 ast_channel_unlock(current.chan1); 15149 copy_request(¤t.req, req); 15150 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15151 p->refer->status = REFER_200OK; 15152 append_history(p, "Xfer", "REFER to call parking."); 15153 if (sipdebug && option_debug > 3) 15154 ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 15155 sip_park(current.chan2, current.chan1, req, seqno); 15156 return res; 15157 } 15158 15159 /* Blind transfers and remote attended xfers */ 15160 transmit_response(p, "202 Accepted", req); 15161 15162 if (current.chan1 && current.chan2) { 15163 if (option_debug > 2) 15164 ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name); 15165 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 15166 } 15167 if (current.chan2) { 15168 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 15169 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 15170 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 15171 /* One for the new channel */ 15172 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 15173 /* Attended transfer to remote host, prepare headers for the INVITE */ 15174 if (p->refer->referred_by) 15175 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 15176 } 15177 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 15178 if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) { 15179 char tempheader[SIPBUFSIZE]; 15180 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 15181 p->refer->replaces_callid_totag ? ";to-tag=" : "", 15182 p->refer->replaces_callid_totag, 15183 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 15184 p->refer->replaces_callid_fromtag); 15185 if (current.chan2) 15186 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 15187 } 15188 /* Must release lock now, because it will not longer 15189 be accessible after the transfer! */ 15190 *nounlock = 1; 15191 ast_channel_unlock(current.chan1); 15192 15193 /* Connect the call */ 15194 15195 /* FAKE ringing if not attended transfer */ 15196 if (!p->refer->attendedtransfer) 15197 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 15198 15199 /* For blind transfer, this will lead to a new call */ 15200 /* For attended transfer to remote host, this will lead to 15201 a new SIP call with a replaces header, if the dial plan allows it 15202 */ 15203 if (!current.chan2) { 15204 /* We have no bridge, so we're talking with Asterisk somehow */ 15205 /* We need to masquerade this call */ 15206 /* What to do to fix this situation: 15207 * Set up the new call in a new channel 15208 * Let the new channel masq into this channel 15209 Please add that code here :-) 15210 */ 15211 p->refer->status = REFER_FAILED; 15212 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 15213 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15214 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 15215 return -1; 15216 } 15217 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 15218 15219 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 15220 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 15221 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 15222 15223 if (!res) { 15224 /* Success - we have a new channel */ 15225 if (option_debug > 2) 15226 ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 15227 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 15228 if (p->refer->localtransfer) 15229 p->refer->status = REFER_200OK; 15230 if (p->owner) 15231 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 15232 append_history(p, "Xfer", "Refer succeeded."); 15233 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15234 /* Do not hangup call, the other side do that when we say 200 OK */ 15235 /* We could possibly implement a timer here, auto congestion */ 15236 res = 0; 15237 } else { 15238 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 15239 if (option_debug > 2) 15240 ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 15241 append_history(p, "Xfer", "Refer failed."); 15242 /* Failure of some kind */ 15243 p->refer->status = REFER_FAILED; 15244 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 15245 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15246 res = -1; 15247 } 15248 return res; 15249 }
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 15744 of file chan_sip.c.
References append_history, ast_inet_ntoa(), ast_log(), ast_test_flag, ast_verbose(), AUTH_ACL_FAILED, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, check_via(), copy_request(), DEFAULT_TRANS_TIMEOUT, get_header(), sip_pvt::initreq, LOG_NOTICE, register_verify(), SIP_PKT_DEBUG, and sip_scheddestroy().
Referenced by handle_request().
15745 { 15746 enum check_auth_result res; 15747 15748 /* Use this as the basis */ 15749 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15750 ast_verbose("Using latest REGISTER request as basis request\n"); 15751 copy_request(&p->initreq, req); 15752 check_via(p, req); 15753 if ((res = register_verify(p, sin, req, e)) < 0) { 15754 const char *reason; 15755 15756 switch (res) { 15757 case AUTH_SECRET_FAILED: 15758 reason = "Wrong password"; 15759 break; 15760 case AUTH_USERNAME_MISMATCH: 15761 reason = "Username/auth name mismatch"; 15762 break; 15763 case AUTH_NOT_FOUND: 15764 reason = "No matching peer found"; 15765 break; 15766 case AUTH_UNKNOWN_DOMAIN: 15767 reason = "Not a local domain"; 15768 break; 15769 case AUTH_PEER_NOT_DYNAMIC: 15770 reason = "Peer is not supposed to register"; 15771 break; 15772 case AUTH_ACL_FAILED: 15773 reason = "Device does not match ACL"; 15774 break; 15775 default: 15776 reason = "Unknown failure"; 15777 break; 15778 } 15779 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 15780 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 15781 reason); 15782 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 15783 } else 15784 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 15785 15786 if (res < 1) { 15787 /* Destroy the session, but keep us around for just a bit in case they don't 15788 get our 200 OK */ 15789 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15790 } 15791 return res; 15792 }
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 15447 of file chan_sip.c.
References append_history, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_extension_state_del(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), sip_pvt::callid, cb_extensionstate(), check_user_full(), check_via(), sip_pvt::context, copy_request(), CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, sip_pvt::expiry, sip_pvt::exten, FALSE, sip_pvt::flags, get_destination(), get_header(), gettag(), sip_request::headers, iflist, iflock, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::laststate, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, sip_peer::mailbox, make_our_tag(), sip_request::method, sip_peer::mwipvt, sip_peer::name, sip_pvt::next, NONE, option_debug, parse_ok_contact(), PIDF_XML, sip_pvt::relatedpeer, sip_pvt::sa, sip_cancel_destroy(), sip_destroy(), sip_destroy_peer(), sip_methods, SIP_NEEDDESTROY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_scheddestroy(), sip_send_mwi_to_peer(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stateid, sip_pvt::subscribecontext, sip_pvt::subscribed, sip_pvt::subscribeuri, sip_pvt::tag, cfsip_methods::text, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_state_notify(), sip_pvt::useragent, sip_pvt::username, and XPIDF_XML.
Referenced by handle_request().
15448 { 15449 int gotdest; 15450 int res = 0; 15451 int firststate = AST_EXTENSION_REMOVED; 15452 struct sip_peer *authpeer = NULL; 15453 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 15454 const char *accept = get_header(req, "Accept"); 15455 int resubscribe = (p->subscribed != NONE); 15456 char *temp, *event; 15457 15458 if (p->initreq.headers) { 15459 /* We already have a dialog */ 15460 if (p->initreq.method != SIP_SUBSCRIBE) { 15461 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 15462 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 15463 transmit_response(p, "403 Forbidden (within dialog)", req); 15464 /* Do not destroy session, since we will break the call if we do */ 15465 if (option_debug) 15466 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); 15467 return 0; 15468 } else if (ast_test_flag(req, SIP_PKT_DEBUG)) { 15469 if (option_debug) { 15470 if (resubscribe) 15471 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 15472 else 15473 ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid); 15474 } 15475 } 15476 } 15477 15478 /* Check if we have a global disallow setting on subscriptions. 15479 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 15480 */ 15481 if (!global_allowsubscribe) { 15482 transmit_response(p, "403 Forbidden (policy)", req); 15483 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15484 return 0; 15485 } 15486 15487 if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */ 15488 const char *to = get_header(req, "To"); 15489 char totag[128]; 15490 15491 /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */ 15492 if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) { 15493 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15494 ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n"); 15495 transmit_response(p, "481 Subscription does not exist", req); 15496 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15497 return 0; 15498 } 15499 15500 /* Use this as the basis */ 15501 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15502 ast_verbose("Creating new subscription\n"); 15503 15504 copy_request(&p->initreq, req); 15505 check_via(p, req); 15506 } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE)) 15507 ast_verbose("Ignoring this SUBSCRIBE request\n"); 15508 15509 /* Find parameters to Event: header value and remove them for now */ 15510 if (ast_strlen_zero(eventheader)) { 15511 transmit_response(p, "489 Bad Event", req); 15512 if (option_debug > 1) 15513 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n"); 15514 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15515 return 0; 15516 } 15517 15518 if ( (strchr(eventheader, ';'))) { 15519 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 15520 temp = strchr(event, ';'); 15521 *temp = '\0'; /* Remove any options for now */ 15522 /* We might need to use them later :-) */ 15523 } else 15524 event = (char *) eventheader; /* XXX is this legal ? */ 15525 15526 /* Handle authentication */ 15527 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 15528 /* if an authentication response was sent, we are done here */ 15529 if (res == AUTH_CHALLENGE_SENT) { 15530 if (authpeer) 15531 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15532 return 0; 15533 } 15534 if (res < 0) { 15535 if (res == AUTH_FAKE_AUTH) { 15536 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 15537 transmit_fake_auth_response(p, req, 1); 15538 } else { 15539 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 15540 transmit_response_reliable(p, "403 Forbidden", req); 15541 } 15542 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15543 if (authpeer) 15544 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15545 return 0; 15546 } 15547 15548 /* Check if this user/peer is allowed to subscribe at all */ 15549 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 15550 transmit_response(p, "403 Forbidden (policy)", req); 15551 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15552 if (authpeer) 15553 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15554 return 0; 15555 } 15556 15557 /* Get destination right away */ 15558 gotdest = get_destination(p, NULL); 15559 15560 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 15561 parse_ok_contact(p, req); 15562 15563 build_contact(p); 15564 if (gotdest) { 15565 transmit_response(p, "404 Not Found", req); 15566 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15567 if (authpeer) 15568 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15569 return 0; 15570 } 15571 15572 /* Initialize tag for new subscriptions */ 15573 if (ast_strlen_zero(p->tag)) 15574 make_our_tag(p->tag, sizeof(p->tag)); 15575 15576 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 15577 if (authpeer) /* No need for authpeer here */ 15578 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15579 15580 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 15581 /* Polycom phones only handle xpidf+xml, even if they say they can 15582 handle pidf+xml as well 15583 */ 15584 if (strstr(p->useragent, "Polycom")) { 15585 p->subscribed = XPIDF_XML; 15586 } else if (strstr(accept, "application/pidf+xml")) { 15587 p->subscribed = PIDF_XML; /* RFC 3863 format */ 15588 } else if (strstr(accept, "application/dialog-info+xml")) { 15589 p->subscribed = DIALOG_INFO_XML; 15590 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 15591 } else if (strstr(accept, "application/cpim-pidf+xml")) { 15592 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 15593 } else if (strstr(accept, "application/xpidf+xml")) { 15594 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 15595 } else if (ast_strlen_zero(accept)) { 15596 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 15597 transmit_response(p, "489 Bad Event", req); 15598 15599 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 15600 p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 15601 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15602 return 0; 15603 } 15604 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 15605 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 15606 } else { 15607 /* Can't find a format for events that we know about */ 15608 char mybuf[200]; 15609 snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept); 15610 transmit_response(p, mybuf, req); 15611 15612 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 15613 accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 15614 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15615 return 0; 15616 } 15617 } else if (!strcmp(event, "message-summary")) { 15618 if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) { 15619 /* Format requested that we do not support */ 15620 transmit_response(p, "406 Not Acceptable", req); 15621 if (option_debug > 1) 15622 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept); 15623 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15624 if (authpeer) /* No need for authpeer here */ 15625 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15626 return 0; 15627 } 15628 /* Looks like they actually want a mailbox status 15629 This version of Asterisk supports mailbox subscriptions 15630 The subscribed URI needs to exist in the dial plan 15631 In most devices, this is configurable to the voicemailmain extension you use 15632 */ 15633 if (!authpeer || ast_strlen_zero(authpeer->mailbox)) { 15634 transmit_response(p, "404 Not found (no mailbox)", req); 15635 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15636 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 15637 if (authpeer) /* No need for authpeer here */ 15638 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15639 return 0; 15640 } 15641 15642 p->subscribed = MWI_NOTIFICATION; 15643 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 15644 /* We only allow one subscription per peer */ 15645 sip_destroy(authpeer->mwipvt); 15646 authpeer->mwipvt = p; /* Link from peer to pvt */ 15647 p->relatedpeer = ASTOBJ_REF(authpeer); /* Link from pvt to peer */ 15648 } else { /* At this point, Asterisk does not understand the specified event */ 15649 transmit_response(p, "489 Bad Event", req); 15650 if (option_debug > 1) 15651 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 15652 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15653 if (authpeer) /* No need for authpeer here */ 15654 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15655 return 0; 15656 } 15657 15658 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) { 15659 if (p->stateid > -1) 15660 ast_extension_state_del(p->stateid, cb_extensionstate); 15661 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 15662 } 15663 15664 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 15665 p->lastinvite = seqno; 15666 if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 15667 p->expiry = atoi(get_header(req, "Expires")); 15668 15669 /* check if the requested expiry-time is within the approved limits from sip.conf */ 15670 if (p->expiry > max_expiry) 15671 p->expiry = max_expiry; 15672 if (p->expiry < min_expiry && p->expiry > 0) 15673 p->expiry = min_expiry; 15674 15675 if (sipdebug || option_debug > 1) { 15676 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 15677 ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox); 15678 else 15679 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 15680 } 15681 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 15682 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15683 if (p->expiry > 0) 15684 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 15685 15686 if (p->subscribed == MWI_NOTIFICATION) { 15687 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15688 transmit_response(p, "200 OK", req); 15689 if (p->relatedpeer) { /* Send first notification */ 15690 ASTOBJ_WRLOCK(p->relatedpeer); 15691 sip_send_mwi_to_peer(p->relatedpeer); 15692 ASTOBJ_UNLOCK(p->relatedpeer); 15693 } 15694 } else { 15695 struct sip_pvt *p_old; 15696 15697 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 15698 15699 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)); 15700 transmit_response(p, "404 Not found", req); 15701 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15702 return 0; 15703 } 15704 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15705 transmit_response(p, "200 OK", req); 15706 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 15707 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 15708 /* hide the 'complete' exten/context in the refer_to field for later display */ 15709 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 15710 15711 /* remove any old subscription from this peer for the same exten/context, 15712 as the peer has obviously forgotten about it and it's wasteful to wait 15713 for it to expire and send NOTIFY messages to the peer only to have them 15714 ignored (or generate errors) 15715 */ 15716 ast_mutex_lock(&iflock); 15717 for (p_old = iflist; p_old; p_old = p_old->next) { 15718 if (p_old == p) 15719 continue; 15720 if (p_old->initreq.method != SIP_SUBSCRIBE) 15721 continue; 15722 if (p_old->subscribed == NONE) 15723 continue; 15724 ast_mutex_lock(&p_old->lock); 15725 if (!strcmp(p_old->username, p->username)) { 15726 if (!strcmp(p_old->exten, p->exten) && 15727 !strcmp(p_old->context, p->context)) { 15728 ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY); 15729 ast_mutex_unlock(&p_old->lock); 15730 break; 15731 } 15732 } 15733 ast_mutex_unlock(&p_old->lock); 15734 } 15735 ast_mutex_unlock(&iflock); 15736 } 15737 if (!p->expiry) 15738 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15739 } 15740 return 1; 15741 }
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 12936 of file chan_sip.c.
References __sip_ack(), __sip_semi_ack(), ast_clear_flag, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_set_flag, ast_skip_blanks(), ast_skip_nonblanks(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ast_channel::call_forward, cb_extensionstate(), sip_pvt::context, do_proxy_auth(), sip_pvt::exten, FALSE, find_sdp(), find_sip_method(), sip_pvt::flags, get_header(), gettag(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), hangup_sip2cause(), ast_channel::hangupcause, sip_pvt::laststate, LOG_DEBUG, LOG_NOTICE, MAX_AUTHTRIES, sip_pvt::method, NONE, option_debug, option_verbose, sip_pvt::owner, parse_moved_contact(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_pvt::relatedpeer, SIP_ACK, sip_alreadygone(), SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_STATECHANGEQUEUE, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_REFER, SIP_REGISTER, SIP_SUBSCRIBE, sipdebug, stop_media_flows(), sip_pvt::subscribed, text, sip_pvt::theirtag, transmit_request(), VERBOSE_PREFIX_3, and XMIT_UNRELIABLE.
12937 { 12938 struct ast_channel *owner; 12939 int sipmethod; 12940 int res = 1; 12941 const char *c = get_header(req, "Cseq"); 12942 /* GCC 4.2 complains if I try to cast c as a char * when passing it to ast_skip_nonblanks, so make a copy of it */ 12943 char *c_copy = ast_strdupa(c); 12944 /* Skip the Cseq and its subsequent spaces */ 12945 const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy)); 12946 12947 if (!msg) 12948 msg = ""; 12949 12950 sipmethod = find_sip_method(msg); 12951 12952 owner = p->owner; 12953 if (owner) 12954 owner->hangupcause = hangup_sip2cause(resp); 12955 12956 /* Acknowledge whatever it is destined for */ 12957 if ((resp >= 100) && (resp <= 199)) 12958 __sip_semi_ack(p, seqno, 0, sipmethod); 12959 else 12960 __sip_ack(p, seqno, 0, sipmethod); 12961 12962 /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */ 12963 if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 12964 p->pendinginvite = 0; 12965 12966 /* Get their tag if we haven't already */ 12967 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 12968 char tag[128]; 12969 12970 gettag(req, "To", tag, sizeof(tag)); 12971 ast_string_field_set(p, theirtag, tag); 12972 } 12973 12974 /* RFC 3261 Section 15 specifies that if we receive a 408 or 481 12975 * in response to a BYE, then we should end the current dialog 12976 * and session. It is known that at least one phone manufacturer 12977 * potentially will send a 404 in response to a BYE, so we'll be 12978 * liberal in what we accept and end the dialog and session if we 12979 * receive any of those responses to a BYE. 12980 */ 12981 if ((resp == 404 || resp == 408 || resp == 481) && sipmethod == SIP_BYE) { 12982 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12983 return; 12984 } 12985 12986 if (p->relatedpeer && p->method == SIP_OPTIONS) { 12987 /* We don't really care what the response is, just that it replied back. 12988 Well, as long as it's not a 100 response... since we might 12989 need to hang around for something more "definitive" */ 12990 if (resp != 100) 12991 handle_response_peerpoke(p, resp, req); 12992 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12993 switch(resp) { 12994 case 100: /* 100 Trying */ 12995 case 101: /* 101 Dialog establishment */ 12996 if (sipmethod == SIP_INVITE) 12997 handle_response_invite(p, resp, rest, req, seqno); 12998 break; 12999 case 183: /* 183 Session Progress */ 13000 if (sipmethod == SIP_INVITE) 13001 handle_response_invite(p, resp, rest, req, seqno); 13002 break; 13003 case 180: /* 180 Ringing */ 13004 if (sipmethod == SIP_INVITE) 13005 handle_response_invite(p, resp, rest, req, seqno); 13006 break; 13007 case 182: /* 182 Queued */ 13008 if (sipmethod == SIP_INVITE) 13009 handle_response_invite(p, resp, rest, req, seqno); 13010 break; 13011 case 200: /* 200 OK */ 13012 p->authtries = 0; /* Reset authentication counter */ 13013 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 13014 /* We successfully transmitted a message 13015 or a video update request in INFO */ 13016 /* Nothing happens here - the message is inside a dialog */ 13017 } else if (sipmethod == SIP_INVITE) { 13018 handle_response_invite(p, resp, rest, req, seqno); 13019 } else if (sipmethod == SIP_NOTIFY) { 13020 /* They got the notify, this is the end */ 13021 if (p->owner) { 13022 if (!p->refer) { 13023 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 13024 ast_queue_hangup(p->owner); 13025 } else if (option_debug > 3) 13026 ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n"); 13027 } else { 13028 if (p->subscribed == NONE) 13029 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13030 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 13031 /* Ready to send the next state we have on queue */ 13032 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 13033 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 13034 } 13035 } 13036 } else if (sipmethod == SIP_REGISTER) 13037 res = handle_response_register(p, resp, rest, req, ignore, seqno); 13038 else if (sipmethod == SIP_BYE) { /* Ok, we're ready to go */ 13039 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13040 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 13041 } else if (sipmethod == SIP_SUBSCRIBE) 13042 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 13043 break; 13044 case 202: /* Transfer accepted */ 13045 if (sipmethod == SIP_REFER) 13046 handle_response_refer(p, resp, rest, req, seqno); 13047 break; 13048 case 401: /* Not www-authorized on SIP method */ 13049 if (sipmethod == SIP_INVITE) 13050 handle_response_invite(p, resp, rest, req, seqno); 13051 else if (sipmethod == SIP_REFER) 13052 handle_response_refer(p, resp, rest, req, seqno); 13053 else if (p->registry && sipmethod == SIP_REGISTER) 13054 res = handle_response_register(p, resp, rest, req, ignore, seqno); 13055 else if (sipmethod == SIP_BYE) { 13056 if (ast_strlen_zero(p->authname)) { 13057 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 13058 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 13059 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13060 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) { 13061 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13062 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13063 /* We fail to auth bye on our own call, but still needs to tear down the call. 13064 Life, they call it. */ 13065 } 13066 } else { 13067 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 13068 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13069 } 13070 break; 13071 case 403: /* Forbidden - we failed authentication */ 13072 if (sipmethod == SIP_INVITE) 13073 handle_response_invite(p, resp, rest, req, seqno); 13074 else if (p->registry && sipmethod == SIP_REGISTER) 13075 res = handle_response_register(p, resp, rest, req, ignore, seqno); 13076 else { 13077 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 13078 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13079 } 13080 break; 13081 case 404: /* Not found */ 13082 if (p->registry && sipmethod == SIP_REGISTER) 13083 res = handle_response_register(p, resp, rest, req, ignore, seqno); 13084 else if (sipmethod == SIP_INVITE) 13085 handle_response_invite(p, resp, rest, req, seqno); 13086 else if (owner) 13087 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13088 break; 13089 case 407: /* Proxy auth required */ 13090 if (sipmethod == SIP_INVITE) 13091 handle_response_invite(p, resp, rest, req, seqno); 13092 else if (sipmethod == SIP_REFER) 13093 handle_response_refer(p, resp, rest, req, seqno); 13094 else if (p->registry && sipmethod == SIP_REGISTER) 13095 res = handle_response_register(p, resp, rest, req, ignore, seqno); 13096 else if (sipmethod == SIP_BYE) { 13097 if (ast_strlen_zero(p->authname)) { 13098 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 13099 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 13100 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13101 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 13102 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13103 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13104 } 13105 } else /* We can't handle this, giving up in a bad way */ 13106 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13107 13108 break; 13109 case 408: /* Request timeout - terminate dialog */ 13110 if (sipmethod == SIP_INVITE) 13111 handle_response_invite(p, resp, rest, req, seqno); 13112 else if (sipmethod == SIP_REGISTER) 13113 res = handle_response_register(p, resp, rest, req, ignore, seqno); 13114 else if (sipmethod == SIP_BYE) { 13115 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13116 if (option_debug) 13117 ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 13118 } else { 13119 if (owner) 13120 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13121 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13122 } 13123 break; 13124 case 481: /* Call leg does not exist */ 13125 if (sipmethod == SIP_INVITE) { 13126 handle_response_invite(p, resp, rest, req, seqno); 13127 } else if (sipmethod == SIP_REFER) { 13128 handle_response_refer(p, resp, rest, req, seqno); 13129 } else if (sipmethod == SIP_BYE) { 13130 /* The other side has no transaction to bye, 13131 just assume it's all right then */ 13132 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13133 } else if (sipmethod == SIP_CANCEL) { 13134 /* The other side has no transaction to cancel, 13135 just assume it's all right then */ 13136 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13137 } else { 13138 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13139 /* Guessing that this is not an important request */ 13140 } 13141 break; 13142 case 487: 13143 if (sipmethod == SIP_INVITE) 13144 handle_response_invite(p, resp, rest, req, seqno); 13145 break; 13146 case 488: /* Not acceptable here - codec error */ 13147 if (sipmethod == SIP_INVITE) 13148 handle_response_invite(p, resp, rest, req, seqno); 13149 break; 13150 case 491: /* Pending */ 13151 if (sipmethod == SIP_INVITE) 13152 handle_response_invite(p, resp, rest, req, seqno); 13153 else { 13154 if (option_debug) 13155 ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 13156 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13157 } 13158 break; 13159 case 501: /* Not Implemented */ 13160 if (sipmethod == SIP_INVITE) 13161 handle_response_invite(p, resp, rest, req, seqno); 13162 else if (sipmethod == SIP_REFER) 13163 handle_response_refer(p, resp, rest, req, seqno); 13164 else 13165 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg); 13166 break; 13167 case 603: /* Declined transfer */ 13168 if (sipmethod == SIP_REFER) { 13169 handle_response_refer(p, resp, rest, req, seqno); 13170 break; 13171 } 13172 /* Fallthrough */ 13173 default: 13174 if ((resp >= 300) && (resp < 700)) { 13175 /* Fatal response */ 13176 if ((option_verbose > 2) && (resp != 487)) 13177 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 13178 13179 if (sipmethod == SIP_INVITE) 13180 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 13181 13182 /* XXX Locking issues?? XXX */ 13183 switch(resp) { 13184 case 300: /* Multiple Choices */ 13185 case 301: /* Moved permenantly */ 13186 case 302: /* Moved temporarily */ 13187 case 305: /* Use Proxy */ 13188 parse_moved_contact(p, req); 13189 /* Fall through */ 13190 case 486: /* Busy here */ 13191 case 600: /* Busy everywhere */ 13192 case 603: /* Decline */ 13193 if (p->owner) 13194 ast_queue_control(p->owner, AST_CONTROL_BUSY); 13195 break; 13196 case 482: /* 13197 \note SIP is incapable of performing a hairpin call, which 13198 is yet another failure of not having a layer 2 (again, YAY 13199 IETF for thinking ahead). So we treat this as a call 13200 forward and hope we end up at the right place... */ 13201 if (option_debug) 13202 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 13203 if (p->owner) 13204 ast_string_field_build(p->owner, call_forward, 13205 "Local/%s@%s", p->username, p->context); 13206 /* Fall through */ 13207 case 480: /* Temporarily Unavailable */ 13208 case 404: /* Not Found */ 13209 case 410: /* Gone */ 13210 case 400: /* Bad Request */ 13211 case 500: /* Server error */ 13212 if (sipmethod == SIP_REFER) { 13213 handle_response_refer(p, resp, rest, req, seqno); 13214 break; 13215 } 13216 /* Fall through */ 13217 case 502: /* Bad gateway */ 13218 case 503: /* Service Unavailable */ 13219 case 504: /* Server Timeout */ 13220 if (owner) 13221 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13222 break; 13223 default: 13224 /* Send hangup */ 13225 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE) 13226 ast_queue_hangup(p->owner); 13227 break; 13228 } 13229 /* ACK on invite */ 13230 if (sipmethod == SIP_INVITE) 13231 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13232 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 13233 sip_alreadygone(p); 13234 if (!p->owner) 13235 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13236 } else if ((resp >= 100) && (resp < 200)) { 13237 if (sipmethod == SIP_INVITE) { 13238 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13239 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13240 if (find_sdp(req)) 13241 process_sdp(p, req); 13242 if (p->owner) { 13243 /* Queue a progress frame */ 13244 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 13245 } 13246 } 13247 } else 13248 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)); 13249 } 13250 } else { 13251 /* Responses to OUTGOING SIP requests on INCOMING calls 13252 get handled here. As well as out-of-call message responses */ 13253 if (ast_test_flag(req, SIP_PKT_DEBUG)) 13254 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 13255 13256 if (sipmethod == SIP_INVITE && resp == 200) { 13257 /* Tags in early session is replaced by the tag in 200 OK, which is 13258 the final reply to our INVITE */ 13259 char tag[128]; 13260 13261 gettag(req, "To", tag, sizeof(tag)); 13262 ast_string_field_set(p, theirtag, tag); 13263 } 13264 13265 switch(resp) { 13266 case 200: 13267 if (sipmethod == SIP_INVITE) { 13268 handle_response_invite(p, resp, rest, req, seqno); 13269 } else if (sipmethod == SIP_CANCEL) { 13270 if (option_debug) 13271 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 13272 13273 /* Wait for 487, then destroy */ 13274 } else if (sipmethod == SIP_NOTIFY) { 13275 /* They got the notify, this is the end */ 13276 if (p->owner) { 13277 if (p->refer) { 13278 if (option_debug) 13279 ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n"); 13280 } else 13281 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 13282 /* ast_queue_hangup(p->owner); Disabled */ 13283 } else { 13284 if (!p->subscribed && !p->refer) 13285 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13286 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 13287 /* Ready to send the next state we have on queue */ 13288 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 13289 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 13290 } 13291 } 13292 } else if (sipmethod == SIP_BYE) 13293 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13294 else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) 13295 /* We successfully transmitted a message or 13296 a video update request in INFO */ 13297 ; 13298 else if (sipmethod == SIP_BYE) 13299 /* Ok, we're ready to go */ 13300 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13301 break; 13302 case 202: /* Transfer accepted */ 13303 if (sipmethod == SIP_REFER) 13304 handle_response_refer(p, resp, rest, req, seqno); 13305 break; 13306 case 401: /* www-auth */ 13307 case 407: 13308 if (sipmethod == SIP_REFER) 13309 handle_response_refer(p, resp, rest, req, seqno); 13310 else if (sipmethod == SIP_INVITE) 13311 handle_response_invite(p, resp, rest, req, seqno); 13312 else if (sipmethod == SIP_BYE) { 13313 char *auth, *auth2; 13314 13315 auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate"); 13316 auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization"); 13317 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 13318 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13319 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13320 } 13321 } 13322 break; 13323 case 481: /* Call leg does not exist */ 13324 if (sipmethod == SIP_INVITE) { 13325 /* Re-invite failed */ 13326 handle_response_invite(p, resp, rest, req, seqno); 13327 } else if (sipmethod == SIP_BYE) { 13328 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13329 } else if (sipdebug) { 13330 ast_log (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 13331 } 13332 break; 13333 case 501: /* Not Implemented */ 13334 if (sipmethod == SIP_INVITE) 13335 handle_response_invite(p, resp, rest, req, seqno); 13336 else if (sipmethod == SIP_REFER) 13337 handle_response_refer(p, resp, rest, req, seqno); 13338 break; 13339 case 603: /* Declined transfer */ 13340 if (sipmethod == SIP_REFER) { 13341 handle_response_refer(p, resp, rest, req, seqno); 13342 break; 13343 } 13344 /* Fallthrough */ 13345 default: /* Errors without handlers */ 13346 if ((resp >= 100) && (resp < 200)) { 13347 if (sipmethod == SIP_INVITE) { /* re-invite */ 13348 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13349 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13350 } 13351 } 13352 if ((resp >= 300) && (resp < 700)) { 13353 if ((option_verbose > 2) && (resp != 487)) 13354 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)); 13355 switch(resp) { 13356 case 488: /* Not acceptable here - codec error */ 13357 case 603: /* Decline */ 13358 case 500: /* Server error */ 13359 case 502: /* Bad gateway */ 13360 case 503: /* Service Unavailable */ 13361 case 504: /* Server timeout */ 13362 13363 /* re-invite failed */ 13364 if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) 13365 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13366 break; 13367 } 13368 } 13369 break; 13370 } 13371 } 13372 }
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 12351 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, ast_queue_control(), ast_queue_frame(), ast_queue_hangup(), ast_random(), ast_rtp_set_rtptimers_onhold(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_string_field_free, ast_test_flag, sip_invite_param::auth_type, authenticate(), sip_pvt::authtries, build_route(), sip_pvt::callid, check_pendings(), DEC_CALL_LIMIT, DEC_CALL_RINGING, DEFAULT_TRANS_TIMEOUT, do_proxy_auth(), FALSE, find_sdp(), sip_pvt::flags, get_header(), sip_pvt::initid, sip_pvt::initreq, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, MAX_AUTHTRIES, ast_channel::name, option_debug, sip_pvt::options, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, sip_pvt::rtp, sched, set_address_from_contact(), SIP_ACK, sip_alreadygone(), SIP_ALREADYGONE, sip_cancel_destroy(), sip_handle_t38_reinvite(), SIP_INVITE, SIP_NEEDDESTROY, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PENDINGBYE, SIP_PKT_IGNORE, sip_reinvite_retry(), sip_scheddestroy(), sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, T38_PEER_REINVITE, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::theirtag, transmit_request(), TRUE, ast_channel_tech::type, sip_pvt::udptl, update_call_counter(), sip_pvt::vrtp, sip_pvt::waitid, WWW_AUTH, XMIT_ERROR, and XMIT_UNRELIABLE.
Referenced by handle_response().
12352 { 12353 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 12354 int res = 0; 12355 int xmitres = 0; 12356 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 12357 struct ast_channel *bridgepeer = NULL; 12358 12359 if (option_debug > 3) { 12360 if (reinvite) 12361 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 12362 else 12363 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 12364 } 12365 12366 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */ 12367 if (option_debug) 12368 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 12369 return; 12370 } 12371 12372 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 12373 /* Don't auto congest anymore since we've gotten something useful back */ 12374 AST_SCHED_DEL(sched, p->initid); 12375 12376 /* RFC3261 says we must treat every 1xx response (but not 100) 12377 that we don't recognize as if it was 183. 12378 */ 12379 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183) 12380 resp = 183; 12381 12382 /* Any response between 100 and 199 is PROCEEDING */ 12383 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 12384 p->invitestate = INV_PROCEEDING; 12385 12386 /* Final response, not 200 ? */ 12387 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 12388 p->invitestate = INV_COMPLETED; 12389 12390 12391 switch (resp) { 12392 case 100: /* Trying */ 12393 case 101: /* Dialog establishment */ 12394 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12395 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12396 check_pendings(p); 12397 break; 12398 12399 case 180: /* 180 Ringing */ 12400 case 182: /* 182 Queued */ 12401 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12402 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12403 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12404 ast_queue_control(p->owner, AST_CONTROL_RINGING); 12405 if (p->owner->_state != AST_STATE_UP) { 12406 ast_setstate(p->owner, AST_STATE_RINGING); 12407 } 12408 } 12409 if (find_sdp(req)) { 12410 if (p->invitestate != INV_CANCELLED) 12411 p->invitestate = INV_EARLY_MEDIA; 12412 res = process_sdp(p, req); 12413 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12414 /* Queue a progress frame only if we have SDP in 180 or 182 */ 12415 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12416 } 12417 } 12418 check_pendings(p); 12419 break; 12420 12421 case 183: /* Session progress */ 12422 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12423 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12424 /* Ignore 183 Session progress without SDP */ 12425 if (find_sdp(req)) { 12426 if (p->invitestate != INV_CANCELLED) 12427 p->invitestate = INV_EARLY_MEDIA; 12428 res = process_sdp(p, req); 12429 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12430 /* Queue a progress frame */ 12431 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12432 } 12433 } 12434 check_pendings(p); 12435 break; 12436 12437 case 200: /* 200 OK on invite - someone's answering our call */ 12438 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12439 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12440 p->authtries = 0; 12441 if (find_sdp(req)) { 12442 if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) 12443 if (!reinvite) 12444 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 12445 /* For re-invites, we try to recover */ 12446 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12447 } 12448 12449 /* Parse contact header for continued conversation */ 12450 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 12451 /* This is important when we have a SIP proxy between us and the phone */ 12452 if (outgoing) { 12453 update_call_counter(p, DEC_CALL_RINGING); 12454 parse_ok_contact(p, req); 12455 /* Save Record-Route for any later requests we make on this dialogue */ 12456 if (!reinvite) 12457 build_route(p, req, 1); 12458 12459 if(set_address_from_contact(p)) { 12460 /* Bad contact - we don't know how to reach this device */ 12461 /* We need to ACK, but then send a bye */ 12462 if (!p->route && !ast_test_flag(req, SIP_PKT_IGNORE)) 12463 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12464 } 12465 12466 } 12467 12468 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 12469 struct sip_pvt *bridgepvt = NULL; 12470 12471 if (!bridgepeer->tech) { 12472 ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n"); 12473 break; 12474 } 12475 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 12476 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 12477 if (bridgepvt->udptl) { 12478 if (p->t38.state == T38_PEER_REINVITE) { 12479 sip_handle_t38_reinvite(bridgepeer, p, 0); 12480 ast_rtp_set_rtptimers_onhold(p->rtp); 12481 if (p->vrtp) 12482 ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */ 12483 } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) { 12484 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 12485 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 12486 /* XXXX Should we really destroy this session here, without any response at all??? */ 12487 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12488 } 12489 } else { 12490 if (option_debug > 1) 12491 ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n"); 12492 ast_mutex_lock(&bridgepvt->lock); 12493 bridgepvt->t38.state = T38_DISABLED; 12494 ast_mutex_unlock(&bridgepvt->lock); 12495 if (option_debug) 12496 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type); 12497 p->t38.state = T38_DISABLED; 12498 if (option_debug > 1) 12499 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12500 } 12501 } else { 12502 /* Other side is not a SIP channel */ 12503 if (option_debug > 1) 12504 ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n"); 12505 p->t38.state = T38_DISABLED; 12506 if (option_debug > 1) 12507 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12508 } 12509 } 12510 if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) { 12511 /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */ 12512 p->t38.state = T38_ENABLED; 12513 if (option_debug) 12514 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12515 } 12516 12517 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12518 if (!reinvite) { 12519 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 12520 } else { /* RE-invite */ 12521 ast_queue_frame(p->owner, &ast_null_frame); 12522 } 12523 } else { 12524 /* It's possible we're getting an 200 OK after we've tried to disconnect 12525 by sending CANCEL */ 12526 /* First send ACK, then send bye */ 12527 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12528 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12529 } 12530 /* If I understand this right, the branch is different for a non-200 ACK only */ 12531 p->invitestate = INV_TERMINATED; 12532 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 12533 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 12534 check_pendings(p); 12535 break; 12536 case 407: /* Proxy authentication */ 12537 case 401: /* Www auth */ 12538 /* First we ACK */ 12539 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12540 if (p->options) 12541 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 12542 12543 /* Then we AUTH */ 12544 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 12545 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12546 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 12547 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 12548 if (p->authtries < MAX_AUTHTRIES) 12549 p->invitestate = INV_CALLING; 12550 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 12551 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 12552 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12553 sip_alreadygone(p); 12554 if (p->owner) 12555 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12556 } 12557 } 12558 break; 12559 12560 case 403: /* Forbidden */ 12561 /* First we ACK */ 12562 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12563 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 12564 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) 12565 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12566 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12567 sip_alreadygone(p); 12568 break; 12569 12570 case 404: /* Not found */ 12571 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12572 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12573 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12574 sip_alreadygone(p); 12575 break; 12576 12577 case 408: /* Request timeout */ 12578 case 481: /* Call leg does not exist */ 12579 /* Could be REFER caused INVITE with replaces */ 12580 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 12581 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12582 if (p->owner) 12583 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12584 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12585 break; 12586 case 487: /* Cancelled transaction */ 12587 /* We have sent CANCEL on an outbound INVITE 12588 This transaction is already scheduled to be killed by sip_hangup(). 12589 */ 12590 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12591 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12592 ast_queue_hangup(p->owner); 12593 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 12594 } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12595 update_call_counter(p, DEC_CALL_LIMIT); 12596 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 12597 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12598 sip_alreadygone(p); 12599 } 12600 break; 12601 case 488: /* Not acceptable here */ 12602 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12603 if (reinvite && p->udptl) { 12604 /* If this is a T.38 call, we should go back to 12605 audio. If this is an audio call - something went 12606 terribly wrong since we don't renegotiate codecs, 12607 only IP/port . 12608 */ 12609 p->t38.state = T38_DISABLED; 12610 /* Try to reset RTP timers */ 12611 ast_rtp_set_rtptimers_onhold(p->rtp); 12612 ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n"); 12613 12614 /*! \bug Is there any way we can go back to the audio call on both 12615 sides here? 12616 */ 12617 /* While figuring that out, hangup the call */ 12618 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12619 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12620 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12621 } else if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) { 12622 /* We tried to send T.38 out in an initial INVITE and the remote side rejected it, 12623 right now we can't fall back to audio so totally abort. 12624 */ 12625 p->t38.state = T38_DISABLED; 12626 /* Try to reset RTP timers */ 12627 ast_rtp_set_rtptimers_onhold(p->rtp); 12628 ast_log(LOG_ERROR, "Got error on T.38 initial invite. Bailing out.\n"); 12629 12630 /* The dialog is now terminated */ 12631 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12632 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12633 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12634 sip_alreadygone(p); 12635 } else { 12636 /* We can't set up this call, so give up */ 12637 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12638 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12639 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12640 /* If there's no dialog to end, then mark p as already gone */ 12641 if (!reinvite) 12642 sip_alreadygone(p); 12643 } 12644 break; 12645 case 491: /* Pending */ 12646 /* we really should have to wait a while, then retransmit 12647 * We should support the retry-after at some point 12648 * At this point, we treat this as a congestion if the call is not in UP state 12649 */ 12650 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12651 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12652 if (p->owner->_state != AST_STATE_UP) { 12653 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12654 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12655 } else { 12656 /* This is a re-invite that failed. 12657 * Reset the flag after a while 12658 */ 12659 int wait = 3 + ast_random() % 5; 12660 p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p); 12661 if (option_debug > 2) 12662 ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait); 12663 } 12664 } 12665 break; 12666 12667 case 501: /* Not implemented */ 12668 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12669 if (p->owner) 12670 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12671 break; 12672 } 12673 if (xmitres == XMIT_ERROR) 12674 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 12675 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 12869 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_tvdiff_ms(), ast_tvnow(), ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::call, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, EVENT_FLAG_SYSTEM, sip_pvt::flags, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::maxms, sip_peer::name, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::relatedpeer, s, sched, sip_destroy_peer(), SIP_NEEDDESTROY, and sip_poke_peer_s().
Referenced by handle_response().
12870 { 12871 struct sip_peer *peer = p->relatedpeer; 12872 int statechanged, is_reachable, was_reachable; 12873 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 12874 12875 /* 12876 * Compute the response time to a ping (goes in peer->lastms.) 12877 * -1 means did not respond, 0 means unknown, 12878 * 1..maxms is a valid response, >maxms means late response. 12879 */ 12880 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 12881 pingtime = 1; 12882 12883 /* Now determine new state and whether it has changed. 12884 * Use some helper variables to simplify the writing 12885 * of the expressions. 12886 */ 12887 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 12888 is_reachable = pingtime <= peer->maxms; 12889 statechanged = peer->lastms == 0 /* yes, unknown before */ 12890 || was_reachable != is_reachable; 12891 12892 peer->lastms = pingtime; 12893 peer->call = NULL; 12894 if (statechanged) { 12895 const char *s = is_reachable ? "Reachable" : "Lagged"; 12896 12897 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 12898 peer->name, s, pingtime, peer->maxms); 12899 ast_device_state_changed("SIP/%s", peer->name); 12900 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 12901 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 12902 peer->name, s, pingtime); 12903 } 12904 12905 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 12906 struct sip_peer *peer_ptr = peer; 12907 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 12908 } 12909 12910 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12911 12912 /* Try again eventually */ 12913 peer->pokeexpire = ast_sched_add(sched, 12914 is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, 12915 sip_poke_peer_s, ASTOBJ_REF(peer)); 12916 12917 if (peer->pokeexpire == -1) { 12918 ASTOBJ_UNREF(peer, sip_destroy_peer); 12919 } 12920 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 12680 of file chan_sip.c.
References AST_CONTROL_CONGESTION, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_set_flag, ast_strlen_zero(), sip_pvt::authname, sip_pvt::authtries, sip_pvt::callid, do_proxy_auth(), sip_pvt::flags, get_header(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, option_debug, sip_pvt::owner, sip_pvt::recv, sip_pvt::refer, REFER_ACCEPTED, REFER_FAILED, REFER_NOAUTH, sip_refer::refer_to, SIP_NEEDDESTROY, SIP_REFER, and sip_refer::status.
Referenced by handle_response().
12681 { 12682 char *auth = "Proxy-Authenticate"; 12683 char *auth2 = "Proxy-Authorization"; 12684 12685 /* If no refer structure exists, then do nothing */ 12686 if (!p->refer) 12687 return; 12688 12689 switch (resp) { 12690 case 202: /* Transfer accepted */ 12691 /* We need to do something here */ 12692 /* The transferee is now sending INVITE to target */ 12693 p->refer->status = REFER_ACCEPTED; 12694 /* Now wait for next message */ 12695 if (option_debug > 2) 12696 ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n"); 12697 /* We should hang along, waiting for NOTIFY's here */ 12698 break; 12699 12700 case 401: /* Not www-authorized on SIP method */ 12701 case 407: /* Proxy auth */ 12702 if (ast_strlen_zero(p->authname)) { 12703 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 12704 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12705 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12706 } 12707 if (resp == 401) { 12708 auth = "WWW-Authenticate"; 12709 auth2 = "Authorization"; 12710 } 12711 if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) { 12712 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 12713 p->refer->status = REFER_NOAUTH; 12714 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12715 } 12716 break; 12717 case 481: /* Call leg does not exist */ 12718 12719 /* A transfer with Replaces did not work */ 12720 /* OEJ: We should Set flag, cancel the REFER, go back 12721 to original call - but right now we can't */ 12722 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 12723 if (p->owner) 12724 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12725 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12726 break; 12727 12728 case 500: /* Server error */ 12729 case 501: /* Method not implemented */ 12730 /* Return to the current call onhold */ 12731 /* Status flag needed to be reset */ 12732 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 12733 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12734 p->refer->status = REFER_FAILED; 12735 break; 12736 case 603: /* Transfer declined */ 12737 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 12738 p->refer->status = REFER_FAILED; 12739 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12740 break; 12741 } 12742 }
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 12745 of file chan_sip.c.
References __get_header(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_strlen_zero(), ASTOBJ_UNREF, sip_pvt::authtries, sip_registry::call, sip_registry::contact, DEFAULT_TRANS_TIMEOUT, do_register_auth(), EVENT_FLAG_SYSTEM, sip_registry::expire, EXPIRY_GUARD_LIMIT, EXPIRY_GUARD_MIN, EXPIRY_GUARD_PCT, EXPIRY_GUARD_SECS, sip_pvt::flags, get_header(), sip_registry::hostname, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, manager_event(), MAX, MAX_AUTHTRIES, option_debug, sip_pvt::our_contact, sip_pvt::peername, sip_registry::refresh, REG_STATE_REGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), sip_registry::regtime, S_OR, sched, SIP_NEEDDESTROY, sip_registry_destroy(), sip_reregister(), sip_scheddestroy(), sipdebug, sip_registry::timeout, sip_pvt::username, and sip_registry::username.
Referenced by handle_response().
12746 { 12747 int expires, expires_ms; 12748 struct sip_registry *r; 12749 r=p->registry; 12750 12751 switch (resp) { 12752 case 401: /* Unauthorized */ 12753 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 12754 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 12755 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12756 } 12757 break; 12758 case 403: /* Forbidden */ 12759 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 12760 if (global_regattempts_max) 12761 p->registry->regattempts = global_regattempts_max+1; 12762 AST_SCHED_DEL(sched, r->timeout); 12763 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12764 break; 12765 case 404: /* Not found */ 12766 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 12767 if (global_regattempts_max) 12768 p->registry->regattempts = global_regattempts_max+1; 12769 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12770 r->call = NULL; 12771 AST_SCHED_DEL(sched, r->timeout); 12772 break; 12773 case 407: /* Proxy auth */ 12774 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 12775 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 12776 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12777 } 12778 break; 12779 case 408: /* Request timeout */ 12780 /* Got a timeout response, so reset the counter of failed responses */ 12781 r->regattempts = 0; 12782 break; 12783 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 12784 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 12785 if (global_regattempts_max) 12786 p->registry->regattempts = global_regattempts_max+1; 12787 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12788 r->call = NULL; 12789 AST_SCHED_DEL(sched, r->timeout); 12790 break; 12791 case 200: /* 200 OK */ 12792 if (!r) { 12793 ast_log(LOG_WARNING, "Got 200 OK on REGISTER, but there isn't a registry entry for '%s' (we probably already got the OK)\n", S_OR(p->peername, p->username)); 12794 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12795 return 0; 12796 } 12797 12798 r->regstate = REG_STATE_REGISTERED; 12799 r->regtime = time(NULL); /* Reset time of last succesful registration */ 12800 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 12801 r->regattempts = 0; 12802 if (option_debug) 12803 ast_log(LOG_DEBUG, "Registration successful\n"); 12804 if (r->timeout > -1) { 12805 if (option_debug) 12806 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 12807 } 12808 AST_SCHED_DEL(sched, r->timeout); 12809 r->call = NULL; 12810 p->registry = NULL; 12811 /* Let this one hang around until we have all the responses */ 12812 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12813 /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */ 12814 12815 /* set us up for re-registering */ 12816 /* figure out how long we got registered for */ 12817 AST_SCHED_DEL(sched, r->expire); 12818 /* according to section 6.13 of RFC, contact headers override 12819 expires headers, so check those first */ 12820 expires = 0; 12821 12822 /* XXX todo: try to save the extra call */ 12823 if (!ast_strlen_zero(get_header(req, "Contact"))) { 12824 const char *contact = NULL; 12825 const char *tmptmp = NULL; 12826 int start = 0; 12827 for(;;) { 12828 contact = __get_header(req, "Contact", &start); 12829 /* this loop ensures we get a contact header about our register request */ 12830 if(!ast_strlen_zero(contact)) { 12831 if( (tmptmp=strstr(contact, p->our_contact))) { 12832 contact=tmptmp; 12833 break; 12834 } 12835 } else 12836 break; 12837 } 12838 tmptmp = strcasestr(contact, "expires="); 12839 if (tmptmp) { 12840 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 12841 expires = 0; 12842 } 12843 12844 } 12845 if (!expires) 12846 expires=atoi(get_header(req, "expires")); 12847 if (!expires) 12848 expires=default_expiry; 12849 12850 expires_ms = expires * 1000; 12851 if (expires <= EXPIRY_GUARD_LIMIT) 12852 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 12853 else 12854 expires_ms -= EXPIRY_GUARD_SECS * 1000; 12855 if (sipdebug) 12856 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 12857 12858 r->refresh= (int) expires_ms / 1000; 12859 12860 /* Schedule re-registration before we expire */ 12861 AST_SCHED_DEL(sched, r->expire); 12862 r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 12863 ASTOBJ_UNREF(r, sip_registry_destroy); 12864 } 12865 return 1; 12866 }
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 3500 of file chan_sip.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CHAN_NOT_IMPLEMENTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_ROUTE_TRANSIT_NET, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL_UNSPECIFIED, AST_CAUSE_NOTDEFINED, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNALLOCATED, AST_CAUSE_UNREGISTERED, AST_CAUSE_USER_BUSY, ast_log(), LOG_DEBUG, and option_debug.
Referenced by sip_hangup().
03501 { 03502 switch (cause) { 03503 case AST_CAUSE_UNALLOCATED: /* 1 */ 03504 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 03505 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 03506 return "404 Not Found"; 03507 case AST_CAUSE_CONGESTION: /* 34 */ 03508 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 03509 return "503 Service Unavailable"; 03510 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 03511 return "408 Request Timeout"; 03512 case AST_CAUSE_NO_ANSWER: /* 19 */ 03513 case AST_CAUSE_UNREGISTERED: /* 20 */ 03514 return "480 Temporarily unavailable"; 03515 case AST_CAUSE_CALL_REJECTED: /* 21 */ 03516 return "403 Forbidden"; 03517 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 03518 return "410 Gone"; 03519 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 03520 return "480 Temporarily unavailable"; 03521 case AST_CAUSE_INVALID_NUMBER_FORMAT: 03522 return "484 Address incomplete"; 03523 case AST_CAUSE_USER_BUSY: 03524 return "486 Busy here"; 03525 case AST_CAUSE_FAILURE: 03526 return "500 Server internal failure"; 03527 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 03528 return "501 Not Implemented"; 03529 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 03530 return "503 Service Unavailable"; 03531 /* Used in chan_iax2 */ 03532 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 03533 return "502 Bad Gateway"; 03534 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 03535 return "488 Not Acceptable Here"; 03536 03537 case AST_CAUSE_NOTDEFINED: 03538 default: 03539 if (option_debug) 03540 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 03541 return NULL; 03542 } 03543 03544 /* Never reached */ 03545 return 0; 03546 }
static int hangup_sip2cause | ( | int | cause | ) | [static] |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 3388 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().
03389 { 03390 /* Possible values taken from causes.h */ 03391 03392 switch(cause) { 03393 case 401: /* Unauthorized */ 03394 return AST_CAUSE_CALL_REJECTED; 03395 case 403: /* Not found */ 03396 return AST_CAUSE_CALL_REJECTED; 03397 case 404: /* Not found */ 03398 return AST_CAUSE_UNALLOCATED; 03399 case 405: /* Method not allowed */ 03400 return AST_CAUSE_INTERWORKING; 03401 case 407: /* Proxy authentication required */ 03402 return AST_CAUSE_CALL_REJECTED; 03403 case 408: /* No reaction */ 03404 return AST_CAUSE_NO_USER_RESPONSE; 03405 case 409: /* Conflict */ 03406 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 03407 case 410: /* Gone */ 03408 return AST_CAUSE_UNALLOCATED; 03409 case 411: /* Length required */ 03410 return AST_CAUSE_INTERWORKING; 03411 case 413: /* Request entity too large */ 03412 return AST_CAUSE_INTERWORKING; 03413 case 414: /* Request URI too large */ 03414 return AST_CAUSE_INTERWORKING; 03415 case 415: /* Unsupported media type */ 03416 return AST_CAUSE_INTERWORKING; 03417 case 420: /* Bad extension */ 03418 return AST_CAUSE_NO_ROUTE_DESTINATION; 03419 case 480: /* No answer */ 03420 return AST_CAUSE_NO_ANSWER; 03421 case 481: /* No answer */ 03422 return AST_CAUSE_INTERWORKING; 03423 case 482: /* Loop detected */ 03424 return AST_CAUSE_INTERWORKING; 03425 case 483: /* Too many hops */ 03426 return AST_CAUSE_NO_ANSWER; 03427 case 484: /* Address incomplete */ 03428 return AST_CAUSE_INVALID_NUMBER_FORMAT; 03429 case 485: /* Ambigous */ 03430 return AST_CAUSE_UNALLOCATED; 03431 case 486: /* Busy everywhere */ 03432 return AST_CAUSE_BUSY; 03433 case 487: /* Request terminated */ 03434 return AST_CAUSE_INTERWORKING; 03435 case 488: /* No codecs approved */ 03436 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03437 case 491: /* Request pending */ 03438 return AST_CAUSE_INTERWORKING; 03439 case 493: /* Undecipherable */ 03440 return AST_CAUSE_INTERWORKING; 03441 case 500: /* Server internal failure */ 03442 return AST_CAUSE_FAILURE; 03443 case 501: /* Call rejected */ 03444 return AST_CAUSE_FACILITY_REJECTED; 03445 case 502: 03446 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03447 case 503: /* Service unavailable */ 03448 return AST_CAUSE_CONGESTION; 03449 case 504: /* Gateway timeout */ 03450 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 03451 case 505: /* SIP version not supported */ 03452 return AST_CAUSE_INTERWORKING; 03453 case 600: /* Busy everywhere */ 03454 return AST_CAUSE_USER_BUSY; 03455 case 603: /* Decline */ 03456 return AST_CAUSE_CALL_REJECTED; 03457 case 604: /* Does not exist anywhere */ 03458 return AST_CAUSE_UNALLOCATED; 03459 case 606: /* Not acceptable */ 03460 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03461 default: 03462 return AST_CAUSE_NORMAL; 03463 } 03464 /* Never reached */ 03465 return 0; 03466 }
static int init_req | ( | struct sip_request * | req, | |
int | sipmethod, | |||
const char * | recip | |||
) | [static] |
Initialize SIP request.
Definition at line 6022 of file chan_sip.c.
References sip_methods, and cfsip_methods::text.
06023 { 06024 /* Initialize a request */ 06025 memset(req, 0, sizeof(*req)); 06026 req->method = sipmethod; 06027 req->header[0] = req->data; 06028 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 06029 req->len = strlen(req->header[0]); 06030 req->headers++; 06031 return 0; 06032 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 6009 of file chan_sip.c.
References SIP_RESPONSE.
06010 { 06011 /* Initialize a response */ 06012 memset(resp, 0, sizeof(*resp)); 06013 resp->method = SIP_RESPONSE; 06014 resp->header[0] = resp->data; 06015 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 06016 resp->len = strlen(resp->header[0]); 06017 resp->headers++; 06018 return 0; 06019 }
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 1664 of file chan_sip.c.
References ast_log(), ast_test_flag, ast_verbose(), sip_pvt::callid, copy_request(), sip_request::headers, sip_pvt::initreq, sip_request::lines, LOG_DEBUG, option_debug, parse_request(), and SIP_PKT_DEBUG.
Referenced by transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), transmit_reinvite_with_t38_sdp(), and transmit_sip_request().
01665 { 01666 if (p->initreq.headers && option_debug) { 01667 ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 01668 } 01669 /* Use this as the basis */ 01670 copy_request(&p->initreq, req); 01671 parse_request(&p->initreq); 01672 if (ast_test_flag(req, SIP_PKT_DEBUG)) 01673 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 01674 }
static void initreqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod | |||
) | [static] |
Initiate new SIP request to peer/user.
Definition at line 7115 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::callid, sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, DEFAULT_MAX_FORWARDS, exten, sip_pvt::flags, sip_pvt::fromdomain, sip_pvt::fromname, sip_pvt::fromuser, sip_pvt::fullcontact, init_req(), sip_pvt::lastmsg, sip_pvt::ocseq, sip_pvt::options, sip_pvt::our_contact, sip_pvt::ourip, ourport, sip_pvt::owner, sip_pvt::rpid, s, S_OR, sip_pvt::sa, SIP_INVITE, sip_methods, SIP_NOTIFY, SIP_SENDRPID, SIP_USEREQPHONE, SIPBUFSIZE, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, sip_pvt::tohost, sip_pvt::uri, sip_invite_param::uri_options, sip_pvt::username, sip_pvt::via, and sip_invite_param::vxml_url.
Referenced by sip_notify(), transmit_invite(), and transmit_notify_with_mwi().
07116 { 07117 char invite_buf[256] = ""; 07118 char *invite = invite_buf; 07119 size_t invite_max = sizeof(invite_buf); 07120 char from[256]; 07121 char to[256]; 07122 char tmp[SIPBUFSIZE/2]; 07123 char tmp2[SIPBUFSIZE/2]; 07124 const char *l = NULL, *n = NULL; 07125 const char *urioptions = ""; 07126 07127 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 07128 const char *s = p->username; /* being a string field, cannot be NULL */ 07129 07130 /* Test p->username against allowed characters in AST_DIGIT_ANY 07131 If it matches the allowed characters list, then sipuser = ";user=phone" 07132 If not, then sipuser = "" 07133 */ 07134 /* + is allowed in first position in a tel: uri */ 07135 if (*s == '+') 07136 s++; 07137 for (; *s; s++) { 07138 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 07139 break; 07140 } 07141 /* If we have only digits, add ;user=phone to the uri */ 07142 if (!*s) 07143 urioptions = ";user=phone"; 07144 } 07145 07146 07147 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 07148 07149 if (p->owner) { 07150 l = p->owner->cid.cid_num; 07151 n = p->owner->cid.cid_name; 07152 } 07153 /* if we are not sending RPID and user wants his callerid restricted */ 07154 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 07155 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 07156 l = CALLERID_UNKNOWN; 07157 n = l; 07158 } 07159 if (ast_strlen_zero(l)) 07160 l = default_callerid; 07161 if (ast_strlen_zero(n)) 07162 n = l; 07163 /* Allow user to be overridden */ 07164 if (!ast_strlen_zero(p->fromuser)) 07165 l = p->fromuser; 07166 else /* Save for any further attempts */ 07167 ast_string_field_set(p, fromuser, l); 07168 07169 /* Allow user to be overridden */ 07170 if (!ast_strlen_zero(p->fromname)) 07171 n = p->fromname; 07172 else /* Save for any further attempts */ 07173 ast_string_field_set(p, fromname, n); 07174 07175 if (pedanticsipchecking) { 07176 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07177 n = tmp; 07178 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 07179 l = tmp2; 07180 } 07181 07182 if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain)) 07183 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); 07184 else 07185 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag); 07186 07187 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 07188 if (!ast_strlen_zero(p->fullcontact)) { 07189 /* If we have full contact, trust it */ 07190 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 07191 } else { 07192 /* Otherwise, use the username while waiting for registration */ 07193 ast_build_string(&invite, &invite_max, "sip:"); 07194 if (!ast_strlen_zero(p->username)) { 07195 n = p->username; 07196 if (pedanticsipchecking) { 07197 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07198 n = tmp; 07199 } 07200 ast_build_string(&invite, &invite_max, "%s@", n); 07201 } 07202 ast_build_string(&invite, &invite_max, "%s", p->tohost); 07203 if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT) 07204 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 07205 ast_build_string(&invite, &invite_max, "%s", urioptions); 07206 } 07207 07208 /* If custom URI options have been provided, append them */ 07209 if (p->options && !ast_strlen_zero(p->options->uri_options)) 07210 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 07211 07212 ast_string_field_set(p, uri, invite_buf); 07213 07214 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 07215 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 07216 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (!strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag); 07217 } else if (p->options && p->options->vxml_url) { 07218 /* If there is a VXML URL append it to the SIP URL */ 07219 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 07220 } else 07221 snprintf(to, sizeof(to), "<%s>", p->uri); 07222 07223 init_req(req, sipmethod, p->uri); 07224 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 07225 07226 add_header(req, "Via", p->via); 07227 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 07228 * OTOH, then we won't have anything in p->route anyway */ 07229 /* Build Remote Party-ID and From */ 07230 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 07231 build_rpid(p); 07232 add_header(req, "From", p->rpid_from); 07233 } else 07234 add_header(req, "From", from); 07235 add_header(req, "To", to); 07236 ast_string_field_set(p, exten, l); 07237 build_contact(p); 07238 add_header(req, "Contact", p->our_contact); 07239 add_header(req, "Call-ID", p->callid); 07240 add_header(req, "CSeq", tmp); 07241 if (!ast_strlen_zero(global_useragent)) 07242 add_header(req, "User-Agent", global_useragent); 07243 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07244 if (!ast_strlen_zero(p->rpid)) 07245 add_header(req, "Remote-Party-ID", p->rpid); 07246 }
static const char * insecure2str | ( | int | port, | |
int | invite | |||
) | const [static] |
Convert Insecure setting to printable string.
Definition at line 10351 of file chan_sip.c.
Referenced by _sip_show_peer().
10352 { 10353 if (port && invite) 10354 return "port,invite"; 10355 else if (port) 10356 return "port"; 10357 else if (invite) 10358 return "invite"; 10359 else 10360 return "no"; 10361 }
static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 8485 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
08486 { 08487 if (!route) 08488 ast_verbose("list_route: no route\n"); 08489 else { 08490 for (;route; route = route->next) 08491 ast_verbose("list_route: hop: <%s>\n", route->hop); 08492 } 08493 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 18908 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.
18909 { 18910 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 18911 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 18912 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 18913 18914 if (!(sched = sched_context_create())) { 18915 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 18916 return AST_MODULE_LOAD_FAILURE; 18917 } 18918 18919 if (!(io = io_context_create())) { 18920 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 18921 sched_context_destroy(sched); 18922 return AST_MODULE_LOAD_FAILURE; 18923 } 18924 18925 sip_reloadreason = CHANNEL_MODULE_LOAD; 18926 18927 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 18928 return AST_MODULE_LOAD_DECLINE; 18929 18930 /* Make sure we can register our sip channel type */ 18931 if (ast_channel_register(&sip_tech)) { 18932 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 18933 io_context_destroy(io); 18934 sched_context_destroy(sched); 18935 return AST_MODULE_LOAD_FAILURE; 18936 } 18937 18938 /* Register all CLI functions for SIP */ 18939 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 18940 18941 /* Tell the RTP subdriver that we're here */ 18942 ast_rtp_proto_register(&sip_rtp); 18943 18944 /* Tell the UDPTL subdriver that we're here */ 18945 ast_udptl_proto_register(&sip_udptl); 18946 18947 /* Register dialplan applications */ 18948 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 18949 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 18950 18951 /* Register dialplan functions */ 18952 ast_custom_function_register(&sip_header_function); 18953 ast_custom_function_register(&sippeer_function); 18954 ast_custom_function_register(&sipchaninfo_function); 18955 ast_custom_function_register(&checksipdomain_function); 18956 18957 /* Register manager commands */ 18958 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 18959 "List SIP peers (text format)", mandescr_show_peers); 18960 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 18961 "Show SIP peer (text format)", mandescr_show_peer); 18962 18963 sip_poke_all_peers(); 18964 sip_send_all_registers(); 18965 18966 /* And start the monitor for the first time */ 18967 restart_monitor(); 18968 18969 return AST_MODULE_LOAD_SUCCESS; 18970 }
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 14817 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, ast_channel::name, option_debug, sip_pvt::owner, sip_pvt::refer, REFER_200OK, REFER_FAILED, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, sipdebug, sip_refer::status, transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by handle_request_refer().
14818 { 14819 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 14820 /* Chan 2: Call from Asterisk to target */ 14821 int res = 0; 14822 struct sip_pvt *targetcall_pvt; 14823 14824 /* Check if the call ID of the replaces header does exist locally */ 14825 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 14826 transferer->refer->replaces_callid_fromtag))) { 14827 if (transferer->refer->localtransfer) { 14828 /* We did not find the refered call. Sorry, can't accept then */ 14829 transmit_response(transferer, "202 Accepted", req); 14830 /* Let's fake a response from someone else in order 14831 to follow the standard */ 14832 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 14833 append_history(transferer, "Xfer", "Refer failed"); 14834 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 14835 transferer->refer->status = REFER_FAILED; 14836 return -1; 14837 } 14838 /* Fall through for remote transfers that we did not find locally */ 14839 if (option_debug > 2) 14840 ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 14841 return 0; 14842 } 14843 14844 /* Ok, we can accept this transfer */ 14845 transmit_response(transferer, "202 Accepted", req); 14846 append_history(transferer, "Xfer", "Refer accepted"); 14847 if (!targetcall_pvt->owner) { /* No active channel */ 14848 if (option_debug > 3) 14849 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n"); 14850 /* Cancel transfer */ 14851 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 14852 append_history(transferer, "Xfer", "Refer failed"); 14853 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 14854 transferer->refer->status = REFER_FAILED; 14855 ast_mutex_unlock(&targetcall_pvt->lock); 14856 ast_channel_unlock(current->chan1); 14857 return -1; 14858 } 14859 14860 /* We have a channel, find the bridge */ 14861 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 14862 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 14863 14864 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 14865 /* Wrong state of new channel */ 14866 if (option_debug > 3) { 14867 if (target.chan2) 14868 ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 14869 else if (target.chan1->_state != AST_STATE_RING) 14870 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n"); 14871 else 14872 ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n"); 14873 } 14874 } 14875 14876 /* Transfer */ 14877 if (option_debug > 3 && sipdebug) { 14878 if (current->chan2) /* We have two bridges */ 14879 ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 14880 else /* One bridge, propably transfer of IVR/voicemail etc */ 14881 ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 14882 } 14883 14884 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14885 14886 /* Perform the transfer */ 14887 res = attempt_transfer(current, &target); 14888 ast_mutex_unlock(&targetcall_pvt->lock); 14889 if (res) { 14890 /* Failed transfer */ 14891 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 14892 append_history(transferer, "Xfer", "Refer failed"); 14893 transferer->refer->status = REFER_FAILED; 14894 if (targetcall_pvt->owner) 14895 ast_channel_unlock(targetcall_pvt->owner); 14896 /* Right now, we have to hangup, sorry. Bridge is destroyed */ 14897 if (res != -2) 14898 ast_hangup(transferer->owner); 14899 else 14900 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 14901 } else { 14902 /* Transfer succeeded! */ 14903 14904 /* Tell transferer that we're done. */ 14905 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 14906 append_history(transferer, "Xfer", "Refer succeeded"); 14907 transferer->refer->status = REFER_200OK; 14908 if (targetcall_pvt->owner) { 14909 if (option_debug) 14910 ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 14911 ast_channel_unlock(targetcall_pvt->owner); 14912 } 14913 } 14914 return 1; 14915 }
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 4878 of file chan_sip.c.
References t.
Referenced by sipsock_read().
04879 { 04880 int h = 0, t = 0; 04881 int lws = 0; 04882 04883 for (; h < len;) { 04884 /* Eliminate all CRs */ 04885 if (msgbuf[h] == '\r') { 04886 h++; 04887 continue; 04888 } 04889 /* Check for end-of-line */ 04890 if (msgbuf[h] == '\n') { 04891 /* Check for end-of-message */ 04892 if (h + 1 == len) 04893 break; 04894 /* Check for a continuation line */ 04895 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 04896 /* Merge continuation line */ 04897 h++; 04898 continue; 04899 } 04900 /* Propagate LF and start new line */ 04901 msgbuf[t++] = msgbuf[h++]; 04902 lws = 0; 04903 continue; 04904 } 04905 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 04906 if (lws) { 04907 h++; 04908 continue; 04909 } 04910 msgbuf[t++] = msgbuf[h++]; 04911 lws = 1; 04912 continue; 04913 } 04914 msgbuf[t++] = msgbuf[h++]; 04915 if (lws) 04916 lws = 0; 04917 } 04918 msgbuf[t] = '\0'; 04919 return t; 04920 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Make our SIP dialog tag.
Definition at line 4542 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().
04543 { 04544 snprintf(tagbuf, len, "as%08lx", ast_random()); 04545 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10596 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().
10597 { 10598 const char *a[4]; 10599 const char *peer; 10600 int ret; 10601 10602 peer = astman_get_header(m,"Peer"); 10603 if (ast_strlen_zero(peer)) { 10604 astman_send_error(s, m, "Peer: <name> missing."); 10605 return 0; 10606 } 10607 a[0] = "sip"; 10608 a[1] = "show"; 10609 a[2] = "peer"; 10610 a[3] = peer; 10611 10612 ret = _sip_show_peer(1, -1, s, m, 4, a); 10613 astman_append(s, "\r\n\r\n" ); 10614 return ret; 10615 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10147 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().
10148 { 10149 const char *id = astman_get_header(m,"ActionID"); 10150 const char *a[] = {"sip", "show", "peers"}; 10151 char idtext[256] = ""; 10152 int total = 0; 10153 10154 if (!ast_strlen_zero(id)) 10155 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 10156 10157 astman_send_ack(s, m, "Peer status list will follow"); 10158 /* List the peers in separate manager events */ 10159 _sip_show_peers(-1, &total, s, m, 3, a); 10160 /* Send final confirmation */ 10161 astman_append(s, 10162 "Event: PeerlistComplete\r\n" 10163 "ListItems: %d\r\n" 10164 "%s" 10165 "\r\n", total, idtext); 10166 return 0; 10167 }
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 1690 of file chan_sip.c.
References sip_request::len, sip_methods, and text.
Referenced by __sip_semi_ack(), and find_sip_method().
01691 { 01692 int len = strlen(sip_methods[id].text); 01693 int l_name = name ? strlen(name) : 0; 01694 /* true if the string is long enough, and ends with whitespace, and matches */ 01695 return (l_name >= len && name[len] < 33 && 01696 !strncasecmp(sip_methods[id].text, name, len)); 01697 }
static char * nat2str | ( | int | nat | ) | const [static] |
Convert NAT setting to text string.
Definition at line 10050 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().
10051 { 10052 switch(nat) { 10053 case SIP_NAT_NEVER: 10054 return "No"; 10055 case SIP_NAT_ROUTE: 10056 return "Route"; 10057 case SIP_NAT_ALWAYS: 10058 return "Always"; 10059 case SIP_NAT_RFC3581: 10060 return "RFC3581"; 10061 default: 10062 return "Unknown"; 10063 } 10064 }
static void parse_copy | ( | struct sip_request * | dst, | |
const struct sip_request * | src | |||
) | [static] |
Copy SIP request, parse it.
Definition at line 2283 of file chan_sip.c.
References sip_request::data, sip_request::len, and parse_request().
Referenced by send_request(), and send_response().
02284 { 02285 memset(dst, 0, sizeof(*dst)); 02286 memcpy(dst->data, src->data, sizeof(dst->data)); 02287 dst->len = src->len; 02288 parse_request(dst); 02289 }
static void parse_moved_contact | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Parse 302 Moved temporalily response.
Definition at line 12252 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_test_flag, sip_pvt::flags, get_header(), get_in_brackets(), LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), s, SIP_PROMISCREDIR, SIPBUFSIZE, and t.
Referenced by handle_response().
12253 { 12254 char tmp[SIPBUFSIZE]; 12255 char *s, *e, *uri, *t; 12256 char *domain; 12257 12258 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 12259 if ((t = strchr(tmp, ','))) 12260 *t = '\0'; 12261 s = get_in_brackets(tmp); 12262 uri = ast_strdupa(s); 12263 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 12264 if (!strncasecmp(s, "sip:", 4)) 12265 s += 4; 12266 e = strchr(s, ';'); 12267 if (e) 12268 *e = '\0'; 12269 if (option_debug) 12270 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 12271 if (p->owner) 12272 ast_string_field_build(p->owner, call_forward, "SIP/%s", s); 12273 } else { 12274 e = strchr(tmp, '@'); 12275 if (e) { 12276 *e++ = '\0'; 12277 domain = e; 12278 } else { 12279 /* No username part */ 12280 domain = tmp; 12281 } 12282 e = strchr(s, ';'); /* Strip of parameters in the username part */ 12283 if (e) 12284 *e = '\0'; 12285 e = strchr(domain, ';'); /* Strip of parameters in the domain part */ 12286 if (e) 12287 *e = '\0'; 12288 12289 if (!strncasecmp(s, "sip:", 4)) 12290 s += 4; 12291 if (option_debug > 1) 12292 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 12293 if (p->owner) { 12294 pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri); 12295 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 12296 ast_string_field_set(p->owner, call_forward, s); 12297 } 12298 } 12299 }
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 8207 of file chan_sip.c.
References ast_copy_string(), ast_string_field_set, sip_peer::fullcontact, get_header(), get_in_brackets(), SIPBUFSIZE, and TRUE.
Referenced by handle_request_invite(), handle_request_subscribe(), and handle_response_invite().
08208 { 08209 char contact[SIPBUFSIZE]; 08210 char *c; 08211 08212 /* Look for brackets */ 08213 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08214 c = get_in_brackets(contact); 08215 08216 /* Save full contact to call pvt for later bye or re-invite */ 08217 ast_string_field_set(pvt, fullcontact, c); 08218 08219 /* Save URI for later ACKs, BYE or RE-invites */ 08220 ast_string_field_set(pvt, okcontacturi, c); 08221 08222 /* We should return false for URI:s we can't handle, 08223 like sips:, tel:, mailto:,ldap: etc */ 08224 return TRUE; 08225 }
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 8296 of file chan_sip.c.
References sip_peer::addr, ahp, ast_apply_ha(), ast_copy_string(), ast_db_put(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_sched_when(), AST_SENSE_ALLOW, ast_set_flag, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::contactha, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, expire_register(), sip_pvt::expiry, sip_pvt::flags, sip_peer::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), global_contact_ha, hp, inaddrcmp(), sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::name, option_verbose, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_pvt::recv, register_peer_exten(), sched, sip_destroy_peer(), SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_TCP, SIP_PAGE2_TCP_CONNECTED, sip_poke_peer(), SIP_REALTIME, SIPBUFSIZE, sip_pvt::sipoptions, sip_peer::sipoptions, sip_pvt::sockfd, sip_peer::sockfd, STANDARD_SIP_PORT, sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3.
Referenced by register_verify().
08297 { 08298 char contact[SIPBUFSIZE]; 08299 char data[SIPBUFSIZE]; 08300 const char *expires = get_header(req, "Expires"); 08301 int expiry = atoi(expires); 08302 char *curi, *n, *pt; 08303 int port; 08304 const char *useragent; 08305 struct hostent *hp; 08306 struct ast_hostent ahp; 08307 struct sockaddr_in oldsin, testsin; 08308 08309 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08310 08311 if (ast_strlen_zero(expires)) { /* No expires header */ 08312 expires = strcasestr(contact, ";expires="); 08313 if (expires) { 08314 /* XXX bug here, we overwrite the string */ 08315 expires = strsep((char **) &expires, ";"); /* trim ; and beyond */ 08316 if (sscanf(expires + 9, "%d", &expiry) != 1) 08317 expiry = default_expiry; 08318 } else { 08319 /* Nothing has been specified */ 08320 expiry = default_expiry; 08321 } 08322 } 08323 08324 /* Look for brackets */ 08325 curi = contact; 08326 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 08327 strsep(&curi, ";"); /* This is Header options, not URI options */ 08328 curi = get_in_brackets(contact); 08329 08330 /* if they did not specify Contact: or Expires:, they are querying 08331 what we currently have stored as their contact address, so return 08332 it 08333 */ 08334 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 08335 /* If we have an active registration, tell them when the registration is going to expire */ 08336 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 08337 pvt->expiry = ast_sched_when(sched, peer->expire); 08338 return PARSE_REGISTER_QUERY; 08339 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 08340 /* This means remove all registrations and return OK */ 08341 memset(&peer->addr, 0, sizeof(peer->addr)); 08342 if (!AST_SCHED_DEL(sched, peer->expire)) { 08343 struct sip_peer *peer_ptr = peer; 08344 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08345 } 08346 08347 destroy_association(peer); 08348 08349 register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */ 08350 peer->fullcontact[0] = '\0'; 08351 peer->useragent[0] = '\0'; 08352 peer->sipoptions = 0; 08353 peer->lastms = 0; 08354 pvt->expiry = 0; 08355 08356 if (option_verbose > 2) 08357 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name); 08358 08359 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name); 08360 return PARSE_REGISTER_UPDATE; 08361 } 08362 08363 /* Store whatever we got as a contact from the client */ 08364 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 08365 08366 /* For the 200 OK, we should use the received contact */ 08367 ast_string_field_build(pvt, our_contact, "<%s>", curi); 08368 08369 /* Make sure it's a SIP URL */ 08370 if (strncasecmp(curi, "sip:", 4)) { 08371 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 08372 } else 08373 curi += 4; 08374 /* Ditch q */ 08375 curi = strsep(&curi, ";"); 08376 /* Grab host */ 08377 n = strchr(curi, '@'); 08378 if (!n) { 08379 n = curi; 08380 curi = NULL; 08381 } else 08382 *n++ = '\0'; 08383 pt = strchr(n, ':'); 08384 if (pt) { 08385 *pt++ = '\0'; 08386 port = atoi(pt); 08387 } else 08388 port = STANDARD_SIP_PORT; 08389 oldsin = peer->addr; 08390 08391 /* Check that they're allowed to register at this IP */ 08392 /* XXX This could block for a long time XXX */ 08393 hp = ast_gethostbyname(n, &ahp); 08394 if (!hp) { 08395 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 08396 *peer->fullcontact = '\0'; 08397 ast_string_field_set(pvt, our_contact, ""); 08398 return PARSE_REGISTER_FAILED; 08399 } 08400 memcpy(&testsin.sin_addr, hp->h_addr, sizeof(testsin.sin_addr)); 08401 if ( ast_apply_ha(global_contact_ha, &testsin) != AST_SENSE_ALLOW || 08402 ast_apply_ha(peer->contactha, &testsin) != AST_SENSE_ALLOW) { 08403 ast_log(LOG_WARNING, "Host '%s' disallowed by rule\n", n); 08404 *peer->fullcontact = '\0'; 08405 ast_string_field_set(pvt, our_contact, ""); 08406 return PARSE_REGISTER_FAILED; 08407 } 08408 08409 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 08410 peer->addr.sin_family = AF_INET; 08411 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 08412 peer->addr.sin_port = htons(port); 08413 } else { 08414 /* Don't trust the contact field. Just use what they came to us 08415 with */ 08416 peer->addr = pvt->recv; 08417 } 08418 08419 /* Save SIP options profile */ 08420 peer->sipoptions = pvt->sipoptions; 08421 08422 if (curi && ast_strlen_zero(peer->username)) 08423 ast_copy_string(peer->username, curi, sizeof(peer->username)); 08424 08425 if (!AST_SCHED_DEL(sched, peer->expire)) { 08426 struct sip_peer *peer_ptr = peer; 08427 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08428 } 08429 if (expiry > max_expiry) 08430 expiry = max_expiry; 08431 if (expiry < min_expiry) 08432 expiry = min_expiry; 08433 if (ast_test_flag(&peer->flags[0], SIP_REALTIME) && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 08434 peer->expire = -1; 08435 } else { 08436 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08437 if (peer->expire == -1) { 08438 struct sip_peer *peer_ptr = peer; 08439 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08440 } 08441 } 08442 pvt->expiry = expiry; 08443 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); 08444 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08445 ast_db_put("SIP/Registry", peer->name, data); 08446 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08447 08448 /* Is this a new IP address for us? */ 08449 if (option_verbose > 2 && inaddrcmp(&peer->addr, &oldsin)) { 08450 ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s port %d\n", peer->name, ast_inet_ntoa(peer->addr.sin_addr), ntohs(peer->addr.sin_port)); 08451 } 08452 sip_poke_peer(peer); 08453 register_peer_exten(peer, 1); 08454 08455 /* Save User agent */ 08456 useragent = get_header(req, "User-Agent"); 08457 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 08458 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 08459 if (option_verbose > 3) 08460 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 08461 } 08462 08463 /* Allocate A TCP Soccket of incoming connection*/ 08464 if (((!ast_test_flag(&peer->flags[1], SIP_PAGE2_TCP)) || (peer->sockfd != pvt->sockfd)) && (ast_test_flag(&pvt->flags[1], SIP_PAGE2_TCP))) { 08465 ast_set_flag(&peer->flags[1], SIP_PAGE2_TCP); 08466 peer->sockfd=pvt->sockfd; 08467 ast_set_flag(&peer->flags[1], SIP_PAGE2_TCP_CONNECTED); 08468 } 08469 return PARSE_REGISTER_UPDATE; 08470 }
static int parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 4925 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), sip_request::data, determine_firstline_parts(), f, sip_request::header, sip_request::headers, sip_request::line, sip_request::lines, LOG_DEBUG, option_debug, SIP_MAX_HEADERS, SIP_MAX_LINES, and sipdebug.
Referenced by initialize_initreq(), parse_copy(), and sipsock_read().
04926 { 04927 /* Divide fields by NULL's */ 04928 char *c; 04929 int f = 0; 04930 04931 c = req->data; 04932 04933 /* First header starts immediately */ 04934 req->header[f] = c; 04935 while(*c) { 04936 if (*c == '\n') { 04937 /* We've got a new header */ 04938 *c = 0; 04939 04940 if (sipdebug && option_debug > 3) 04941 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04942 if (ast_strlen_zero(req->header[f])) { 04943 /* Line by itself means we're now in content */ 04944 c++; 04945 break; 04946 } 04947 if (f >= SIP_MAX_HEADERS - 1) { 04948 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 04949 } else { 04950 f++; 04951 req->header[f] = c + 1; 04952 } 04953 } else if (*c == '\r') { 04954 /* Ignore but eliminate \r's */ 04955 *c = 0; 04956 } 04957 c++; 04958 } 04959 04960 req->headers = f; 04961 04962 /* Check a non-newline-terminated last header */ 04963 if (!ast_strlen_zero(req->header[f])) { 04964 if (sipdebug && option_debug > 3) 04965 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04966 req->headers++; 04967 } 04968 04969 /* Now we process any body content */ 04970 f = 0; 04971 req->line[f] = c; 04972 while (*c) { 04973 if (*c == '\n') { 04974 /* We've got a new line */ 04975 *c = 0; 04976 if (sipdebug && option_debug > 3) 04977 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 04978 if (f == SIP_MAX_LINES - 1) { 04979 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 04980 break; 04981 } else { 04982 f++; 04983 req->line[f] = c + 1; 04984 } 04985 } else if (*c == '\r') { 04986 /* Ignore and eliminate \r's */ 04987 *c = 0; 04988 } 04989 c++; 04990 } 04991 04992 req->lines = f; 04993 04994 /* Check a non-newline-terminated last line */ 04995 if (!ast_strlen_zero(req->line[f])) { 04996 req->lines++; 04997 } 04998 04999 if (*c) 05000 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 05001 05002 /* Split up the first line parts */ 05003 return determine_firstline_parts(req); 05004 }
static unsigned int parse_sip_options | ( | struct sip_pvt * | pvt, | |
const char * | supported | |||
) | [static] |
Parse supported header in incoming packet.
Definition at line 1714 of file chan_sip.c.
References ast_log(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), FALSE, LOG_DEBUG, sip_request::next, option_debug, sip_options, sipdebug, sip_pvt::sipoptions, text, and TRUE.
Referenced by handle_request_invite().
01715 { 01716 char *next, *sep; 01717 char *temp; 01718 unsigned int profile = 0; 01719 int i, found; 01720 01721 if (ast_strlen_zero(supported) ) 01722 return 0; 01723 temp = ast_strdupa(supported); 01724 01725 if (option_debug > 2 && sipdebug) 01726 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01727 01728 for (next = temp; next; next = sep) { 01729 found = FALSE; 01730 if ( (sep = strchr(next, ',')) != NULL) 01731 *sep++ = '\0'; 01732 next = ast_skip_blanks(next); 01733 if (option_debug > 2 && sipdebug) 01734 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01735 for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) { 01736 if (!strcasecmp(next, sip_options[i].text)) { 01737 profile |= sip_options[i].id; 01738 found = TRUE; 01739 if (option_debug > 2 && sipdebug) 01740 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01741 break; 01742 } 01743 } 01744 if (!found && option_debug > 2 && sipdebug) { 01745 if (!strncasecmp(next, "x-", 2)) 01746 ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next); 01747 else 01748 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01749 } 01750 } 01751 01752 if (pvt) 01753 pvt->sipoptions = profile; 01754 return profile; 01755 }
static int peer_status | ( | struct sip_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
Report Peer status in character string.
Definition at line 10069 of file chan_sip.c.
References ast_copy_string(), sip_peer::lastms, and sip_peer::maxms.
10070 { 10071 int res = 0; 10072 if (peer->maxms) { 10073 if (peer->lastms < 0) { 10074 ast_copy_string(status, "UNREACHABLE", statuslen); 10075 } else if (peer->lastms > peer->maxms) { 10076 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 10077 res = 1; 10078 } else if (peer->lastms) { 10079 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 10080 res = 1; 10081 } else { 10082 ast_copy_string(status, "UNKNOWN", statuslen); 10083 } 10084 } else { 10085 ast_copy_string(status, "Unmonitored", statuslen); 10086 /* Checking if port is 0 */ 10087 res = -1; 10088 } 10089 return res; 10090 }
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 10537 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().
10538 { 10539 int x, codec; 10540 10541 for(x = 0; x < 32 ; x++) { 10542 codec = ast_codec_pref_index(pref, x); 10543 if (!codec) 10544 break; 10545 ast_cli(fd, "%s", ast_getformatname(codec)); 10546 ast_cli(fd, ":%d", pref->framing[x]); 10547 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 10548 ast_cli(fd, ","); 10549 } 10550 if (!x) 10551 ast_cli(fd, "none"); 10552 }
static void print_group | ( | int | fd, | |
ast_group_t | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 10328 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
10329 { 10330 char buf[256]; 10331 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 10332 }
static void process_request_queue | ( | struct sip_pvt * | p, | |
int * | recount, | |||
int * | nounlock | |||
) | [static] |
Definition at line 16015 of file chan_sip.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_log(), handle_request(), LOG_DEBUG, sip_request::next, option_debug, and sip_pvt::request_queue.
Referenced by sipsock_read().
16016 { 16017 struct sip_request *req; 16018 16019 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 16020 if (handle_request(p, req, &p->recv, recount, nounlock) == -1) { 16021 /* Request failed */ 16022 if (option_debug) { 16023 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 16024 } 16025 } 16026 ast_free(req); 16027 } 16028 }
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 5137 of file chan_sip.c.
References ast_clear_flag, ast_codec_choose(), ast_codec_pref_setsize(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_FORMAT_AUDIO_MASK, ast_getformatname_multiple(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_control_data(), ast_queue_frame(), ast_rtp_alloc_size(), ast_rtp_codec_getformat(), ast_rtp_codec_getpref(), ast_rtp_codec_setpref(), AST_RTP_DTMF, ast_rtp_get_current_formats(), ast_rtp_get_peer(), ast_rtp_lookup_mime_multiple(), ast_rtp_new_init(), AST_RTP_OPT_G726_NONSTANDARD, ast_rtp_pt_clear(), ast_rtp_pt_copy(), ast_rtp_set_m_type(), ast_rtp_set_peer(), ast_rtp_set_rtpmap_type(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_stop(), ast_rtp_unset_m_type(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_threadstorage_get(), 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::callid, sip_pvt::capability, t38properties::capability, change_hold_state(), debug, FALSE, sip_pvt::flags, format, get_sdp(), get_sdp_iterate(), hp, sip_pvt::jointcapability, t38properties::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastinvite, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len(), LOG_DEBUG, LOG_ERROR, LOG_NOTICE, MAX_RTP_PT, sip_pvt::mohsuggest, ast_channel::name, ast_channel::nativeformats, sip_pvt::noncodeccapability, option_debug, sip_pvt::owner, sip_pvt::peercapability, t38properties::peercapability, portno, sip_pvt::prefs, ast_channel::readformat, sip_pvt::rtp, s, S_OR, SDP_MAX_RTPMAP_CODECS, sip_request::sdp_start, sip_debug_test_pvt(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_G726_NONSTANDARD, SIP_NAT, SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_UDPTL_DESTINATION, SIPBUFSIZE, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_PEER_DIRECT, T38_PEER_REINVITE, T38FAX_FILL_BIT_REMOVAL, T38FAX_RATE_12000, T38FAX_RATE_14400, T38FAX_RATE_2400, T38FAX_RATE_4800, T38FAX_RATE_7200, T38FAX_RATE_9600, T38FAX_RATE_MANAGEMENT_LOCAL_TCF, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_TRANSCODING_JBIG, T38FAX_TRANSCODING_MMR, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, T38FAX_VERSION_0, T38FAX_VERSION_1, TRUE, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, sip_pvt::vrtp, and ast_channel::writeformat.
05138 { 05139 const char *m; /* SDP media offer */ 05140 const char *c; 05141 const char *a; 05142 char host[258]; 05143 int len = -1; 05144 int portno = -1; /*!< RTP Audio port number */ 05145 int vportno = -1; /*!< RTP Video port number */ 05146 int udptlportno = -1; 05147 int peert38capability = 0; 05148 char s[256]; 05149 int old = 0; 05150 05151 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 05152 int peercapability = 0, peernoncodeccapability = 0; 05153 int vpeercapability = 0, vpeernoncodeccapability = 0; 05154 struct sockaddr_in sin; /*!< media socket address */ 05155 struct sockaddr_in vsin; /*!< Video socket address */ 05156 05157 const char *codecs; 05158 struct hostent *hp; /*!< RTP Audio host IP */ 05159 struct hostent *vhp = NULL; /*!< RTP video host IP */ 05160 struct ast_hostent audiohp; 05161 struct ast_hostent videohp; 05162 int codec; 05163 int destiterator = 0; 05164 int iterator; 05165 int sendonly = -1; 05166 int numberofports; 05167 struct ast_rtp *newaudiortp, *newvideortp; /* Buffers for codec handling */ 05168 int newjointcapability; /* Negotiated capability */ 05169 int newpeercapability; 05170 int newnoncodeccapability; 05171 int numberofmediastreams = 0; 05172 int debug = sip_debug_test_pvt(p); 05173 05174 int found_rtpmap_codecs[SDP_MAX_RTPMAP_CODECS]; 05175 int last_rtpmap_codec=0; 05176 05177 if (!p->rtp) { 05178 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 05179 return -1; 05180 } 05181 05182 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 05183 #ifdef LOW_MEMORY 05184 newaudiortp = ast_threadstorage_get(&ts_audio_rtp, ast_rtp_alloc_size()); 05185 #else 05186 newaudiortp = alloca(ast_rtp_alloc_size()); 05187 #endif 05188 memset(newaudiortp, 0, ast_rtp_alloc_size()); 05189 ast_rtp_new_init(newaudiortp); 05190 ast_rtp_pt_clear(newaudiortp); 05191 05192 #ifdef LOW_MEMORY 05193 newvideortp = ast_threadstorage_get(&ts_video_rtp, ast_rtp_alloc_size()); 05194 #else 05195 newvideortp = alloca(ast_rtp_alloc_size()); 05196 #endif 05197 memset(newvideortp, 0, ast_rtp_alloc_size()); 05198 ast_rtp_new_init(newvideortp); 05199 ast_rtp_pt_clear(newvideortp); 05200 05201 /* Update our last rtprx when we receive an SDP, too */ 05202 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 05203 05204 05205 /* Try to find first media stream */ 05206 m = get_sdp(req, "m"); 05207 destiterator = req->sdp_start; 05208 c = get_sdp_iterate(&destiterator, req, "c"); 05209 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 05210 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 05211 return -1; 05212 } 05213 05214 /* Check for IPv4 address (not IPv6 yet) */ 05215 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05216 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 05217 return -1; 05218 } 05219 05220 /* XXX This could block for a long time, and block the main thread! XXX */ 05221 hp = ast_gethostbyname(host, &audiohp); 05222 if (!hp) { 05223 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 05224 return -1; 05225 } 05226 vhp = hp; /* Copy to video address as default too */ 05227 05228 iterator = req->sdp_start; 05229 ast_set_flag(&p->flags[0], SIP_NOVIDEO); 05230 05231 05232 /* Find media streams in this SDP offer */ 05233 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 05234 int x; 05235 int audio = FALSE; 05236 05237 numberofports = 1; 05238 len = -1; 05239 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05240 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1 && len > 0)) { 05241 audio = TRUE; 05242 numberofmediastreams++; 05243 /* Found audio stream in this media definition */ 05244 portno = x; 05245 /* Scan through the RTP payload types specified in a "m=" line: */ 05246 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05247 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05248 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05249 return -1; 05250 } 05251 if (debug) 05252 ast_verbose("Found RTP audio format %d\n", codec); 05253 ast_rtp_set_m_type(newaudiortp, codec); 05254 } 05255 } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05256 (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1 && len >= 0)) { 05257 /* If it is not audio - is it video ? */ 05258 ast_clear_flag(&p->flags[0], SIP_NOVIDEO); 05259 numberofmediastreams++; 05260 vportno = x; 05261 /* Scan through the RTP payload types specified in a "m=" line: */ 05262 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05263 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05264 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05265 return -1; 05266 } 05267 if (debug) 05268 ast_verbose("Found RTP video format %d\n", codec); 05269 ast_rtp_set_m_type(newvideortp, codec); 05270 } 05271 } else if (p->udptl && ( (sscanf(m, "image %d udptl t38%n", &x, &len) == 1 && len > 0) || 05272 (sscanf(m, "image %d UDPTL t38%n", &x, &len) == 1 && len >= 0) )) { 05273 if (debug) 05274 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 05275 udptlportno = x; 05276 numberofmediastreams++; 05277 05278 if (p->owner && p->lastinvite) { 05279 p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ 05280 if (option_debug > 1) 05281 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); 05282 } else { 05283 p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ 05284 if (option_debug > 1) 05285 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05286 } 05287 } else 05288 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 05289 if (numberofports > 1) 05290 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 05291 05292 05293 /* Check for Media-description-level-address for audio */ 05294 c = get_sdp_iterate(&destiterator, req, "c"); 05295 if (!ast_strlen_zero(c)) { 05296 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05297 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 05298 } else { 05299 /* XXX This could block for a long time, and block the main thread! XXX */ 05300 if (audio) { 05301 if ( !(hp = ast_gethostbyname(host, &audiohp))) { 05302 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c); 05303 return -2; 05304 } 05305 } else if (!(vhp = ast_gethostbyname(host, &videohp))) { 05306 ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c); 05307 return -2; 05308 } 05309 } 05310 05311 } 05312 } 05313 if (portno == -1 && vportno == -1 && udptlportno == -1) 05314 /* No acceptable offer found in SDP - we have no ports */ 05315 /* Do not change RTP or VRTP if this is a re-invite */ 05316 return -2; 05317 05318 if (numberofmediastreams > 2) 05319 /* We have too many fax, audio and/or video media streams, fail this offer */ 05320 return -3; 05321 05322 /* RTP addresses and ports for audio and video */ 05323 sin.sin_family = AF_INET; 05324 vsin.sin_family = AF_INET; 05325 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 05326 if (vhp) 05327 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 05328 05329 /* Setup UDPTL port number */ 05330 if (p->udptl) { 05331 if (udptlportno > 0) { 05332 sin.sin_port = htons(udptlportno); 05333 if (ast_test_flag(&p->flags[0], SIP_NAT) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) { 05334 struct sockaddr_in peer; 05335 ast_rtp_get_peer(p->rtp, &peer); 05336 if (peer.sin_addr.s_addr) { 05337 memcpy(&sin.sin_addr, &peer.sin_addr, sizeof(sin.sin_addr)); 05338 if (debug) { 05339 ast_log(LOG_DEBUG, "Peer T.38 UDPTL is set behind NAT and with destination, destination address now %s\n", ast_inet_ntoa(sin.sin_addr)); 05340 } 05341 } 05342 } 05343 ast_udptl_set_peer(p->udptl, &sin); 05344 if (debug) 05345 ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05346 } else { 05347 ast_udptl_stop(p->udptl); 05348 if (debug) 05349 ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n"); 05350 } 05351 } 05352 05353 05354 if (p->rtp) { 05355 if (portno > 0) { 05356 sin.sin_port = htons(portno); 05357 ast_rtp_set_peer(p->rtp, &sin); 05358 if (debug) 05359 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05360 } else { 05361 if (udptlportno > 0) { 05362 if (debug) 05363 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session. Callid %s\n", p->callid); 05364 } else { 05365 ast_rtp_stop(p->rtp); 05366 if (debug) 05367 ast_verbose("Peer doesn't provide audio. Callid %s\n", p->callid); 05368 } 05369 } 05370 } 05371 /* Setup video port number */ 05372 if (vportno != -1) 05373 vsin.sin_port = htons(vportno); 05374 05375 /* Next, scan through each "a=rtpmap:" line, noting each 05376 * specified RTP payload type (with corresponding MIME subtype): 05377 */ 05378 /* XXX This needs to be done per media stream, since it's media stream specific */ 05379 iterator = req->sdp_start; 05380 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05381 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 05382 if (option_debug > 1) { 05383 int breakout = FALSE; 05384 05385 /* If we're debugging, check for unsupported sdp options */ 05386 if (!strncasecmp(a, "rtcp:", (size_t) 5)) { 05387 if (debug) 05388 ast_verbose("Got unsupported a:rtcp in SDP offer \n"); 05389 breakout = TRUE; 05390 } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) { 05391 /* Format parameters: Not supported */ 05392 /* Note: This is used for codec parameters, like bitrate for 05393 G722 and video formats for H263 and H264 05394 See RFC2327 for an example */ 05395 if (debug) 05396 ast_verbose("Got unsupported a:fmtp in SDP offer \n"); 05397 breakout = TRUE; 05398 } else if (!strncasecmp(a, "framerate:", (size_t) 10)) { 05399 /* Video stuff: Not supported */ 05400 if (debug) 05401 ast_verbose("Got unsupported a:framerate in SDP offer \n"); 05402 breakout = TRUE; 05403 } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) { 05404 /* Video stuff: Not supported */ 05405 if (debug) 05406 ast_verbose("Got unsupported a:maxprate in SDP offer \n"); 05407 breakout = TRUE; 05408 } else if (!strncasecmp(a, "crypto:", (size_t) 7)) { 05409 /* SRTP stuff, not yet supported */ 05410 if (debug) 05411 ast_verbose("Got unsupported a:crypto in SDP offer \n"); 05412 breakout = TRUE; 05413 } 05414 if (breakout) /* We have a match, skip to next header */ 05415 continue; 05416 } 05417 if (!strcasecmp(a, "sendonly")) { 05418 if (sendonly == -1) 05419 sendonly = 1; 05420 continue; 05421 } else if (!strcasecmp(a, "inactive")) { 05422 if (sendonly == -1) 05423 sendonly = 2; 05424 continue; 05425 } else if (!strcasecmp(a, "sendrecv")) { 05426 if (sendonly == -1) 05427 sendonly = 0; 05428 continue; 05429 } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 05430 char *tmp = strrchr(a, ':'); 05431 long int framing = 0; 05432 if (tmp) { 05433 tmp++; 05434 framing = strtol(tmp, NULL, 10); 05435 if (framing == LONG_MIN || framing == LONG_MAX) { 05436 framing = 0; 05437 if (option_debug) 05438 ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a); 05439 } 05440 } 05441 if (framing && p->autoframing) { 05442 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 05443 int codec_n; 05444 int format = 0; 05445 for (codec_n = 0; codec_n < MAX_RTP_PT; codec_n++) { 05446 format = ast_rtp_codec_getformat(codec_n); 05447 if (!format) /* non-codec or not found */ 05448 continue; 05449 if (option_debug) 05450 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 05451 ast_codec_pref_setsize(pref, format, framing); 05452 } 05453 ast_rtp_codec_setpref(p->rtp, pref); 05454 } 05455 continue; 05456 } else if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) == 2) { 05457 /* We have a rtpmap to handle */ 05458 int found = FALSE; 05459 /* We should propably check if this is an audio or video codec 05460 so we know where to look */ 05461 05462 if (last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 05463 /* Note: should really look at the 'freq' and '#chans' params too */ 05464 if(ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 05465 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) { 05466 if (debug) 05467 ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec); 05468 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05469 last_rtpmap_codec++; 05470 found = TRUE; 05471 05472 } else if (p->vrtp) { 05473 if(ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) { 05474 if (debug) 05475 ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec); 05476 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05477 last_rtpmap_codec++; 05478 found = TRUE; 05479 } 05480 } 05481 } else { 05482 if (debug) 05483 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 05484 } 05485 05486 if (!found) { 05487 /* Remove this codec since it's an unknown media type for us */ 05488 /* XXX This is buggy since the media line for audio and video can have the 05489 same numbers. We need to check as described above, but for testing this works... */ 05490 ast_rtp_unset_m_type(newaudiortp, codec); 05491 ast_rtp_unset_m_type(newvideortp, codec); 05492 if (debug) 05493 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 05494 } 05495 } 05496 } 05497 05498 if (udptlportno != -1) { 05499 int found = 0, x; 05500 05501 old = 0; 05502 05503 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 05504 iterator = req->sdp_start; 05505 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05506 if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) { 05507 found = 1; 05508 if (option_debug > 2) 05509 ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x); 05510 } else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1) || (sscanf(a, "T38FaxMaxRate:%d", &x) == 1)) { 05511 found = 1; 05512 if (option_debug > 2) 05513 ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x); 05514 switch (x) { 05515 case 14400: 05516 peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05517 break; 05518 case 12000: 05519 peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05520 break; 05521 case 9600: 05522 peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05523 break; 05524 case 7200: 05525 peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05526 break; 05527 case 4800: 05528 peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 05529 break; 05530 case 2400: 05531 peert38capability |= T38FAX_RATE_2400; 05532 break; 05533 } 05534 } else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) { 05535 found = 1; 05536 if (option_debug > 2) 05537 ast_log(LOG_DEBUG, "FaxVersion: %d\n",x); 05538 if (x == 0) 05539 peert38capability |= T38FAX_VERSION_0; 05540 else if (x == 1) 05541 peert38capability |= T38FAX_VERSION_1; 05542 } else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1) || (sscanf(a, "T38MaxDatagram:%d", &x) == 1)) { 05543 found = 1; 05544 if (option_debug > 2) 05545 ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x); 05546 ast_udptl_set_far_max_datagram(p->udptl, x); 05547 ast_udptl_set_local_max_datagram(p->udptl, x); 05548 } else if ((strncmp(a, "T38FaxFillBitRemoval", 20) == 0)) { 05549 found = 1; 05550 if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) { 05551 if (option_debug > 2) 05552 ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x); 05553 if (x == 1) 05554 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05555 } else { 05556 if (option_debug > 2) 05557 ast_log(LOG_DEBUG, "FillBitRemoval\n"); 05558 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05559 } 05560 } else if ((strncmp(a, "T38FaxTranscodingMMR", 20) == 0)) { 05561 found = 1; 05562 if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) { 05563 if (option_debug > 2) 05564 ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x); 05565 if (x == 1) 05566 peert38capability |= T38FAX_TRANSCODING_MMR; 05567 } else { 05568 if (option_debug > 2) 05569 ast_log(LOG_DEBUG, "Transcoding MMR\n"); 05570 peert38capability |= T38FAX_TRANSCODING_MMR; 05571 } 05572 } else if ((strncmp(a, "T38FaxTranscodingJBIG", 21) == 0)) { 05573 found = 1; 05574 if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) { 05575 if (option_debug > 2) 05576 ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x); 05577 if (x == 1) 05578 peert38capability |= T38FAX_TRANSCODING_JBIG; 05579 } else { 05580 if (option_debug > 2) 05581 ast_log(LOG_DEBUG, "Transcoding JBIG\n"); 05582 peert38capability |= T38FAX_TRANSCODING_JBIG; 05583 } 05584 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 05585 found = 1; 05586 if (option_debug > 2) 05587 ast_log(LOG_DEBUG, "RateManagement: %s\n", s); 05588 if (!strcasecmp(s, "localTCF")) 05589 peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 05590 else if (!strcasecmp(s, "transferredTCF")) 05591 peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 05592 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 05593 found = 1; 05594 if (option_debug > 2) 05595 ast_log(LOG_DEBUG, "UDP EC: %s\n", s); 05596 if (!strcasecmp(s, "t38UDPRedundancy")) { 05597 peert38capability |= T38FAX_UDP_EC_REDUNDANCY; 05598 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 05599 } else if (!strcasecmp(s, "t38UDPFEC")) { 05600 peert38capability |= T38FAX_UDP_EC_FEC; 05601 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 05602 } else { 05603 peert38capability |= T38FAX_UDP_EC_NONE; 05604 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05605 } 05606 } 05607 } 05608 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 05609 p->t38.peercapability = peert38capability; 05610 p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */ 05611 peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 05612 p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */ 05613 } 05614 if (debug) 05615 ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 05616 p->t38.capability, 05617 p->t38.peercapability, 05618 p->t38.jointcapability); 05619 } else { 05620 p->t38.state = T38_DISABLED; 05621 if (option_debug > 2) 05622 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05623 } 05624 05625 /* Now gather all of the codecs that we are asked for: */ 05626 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 05627 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 05628 05629 newjointcapability = p->capability & (peercapability | vpeercapability); 05630 newpeercapability = (peercapability | vpeercapability); 05631 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 05632 05633 05634 if (debug) { 05635 /* shame on whoever coded this.... */ 05636 char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE]; 05637 05638 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 05639 ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability), 05640 ast_getformatname_multiple(s2, SIPBUFSIZE, newpeercapability), 05641 ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability), 05642 ast_getformatname_multiple(s4, SIPBUFSIZE, newjointcapability)); 05643 05644 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 05645 ast_rtp_lookup_mime_multiple(s1, SIPBUFSIZE, p->noncodeccapability, 0, 0), 05646 ast_rtp_lookup_mime_multiple(s2, SIPBUFSIZE, peernoncodeccapability, 0, 0), 05647 ast_rtp_lookup_mime_multiple(s3, SIPBUFSIZE, newnoncodeccapability, 0, 0)); 05648 } 05649 if (!newjointcapability) { 05650 /* If T.38 was not negotiated either, totally bail out... */ 05651 if (!p->t38.jointcapability || !udptlportno) { 05652 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 05653 /* Do NOT Change current setting */ 05654 return -1; 05655 } else { 05656 if (option_debug > 2) 05657 ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n"); 05658 return 0; 05659 } 05660 } 05661 05662 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 05663 they are acceptable */ 05664 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 05665 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 05666 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 05667 05668 ast_rtp_pt_copy(p->rtp, newaudiortp); 05669 if (p->vrtp) 05670 ast_rtp_pt_copy(p->vrtp, newvideortp); 05671 05672 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 05673 ast_clear_flag(&p->flags[0], SIP_DTMF); 05674 if (newnoncodeccapability & AST_RTP_DTMF) { 05675 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 05676 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 05677 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 05678 ast_rtp_setdtmf(p->rtp, 1); 05679 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05680 } else { 05681 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 05682 } 05683 } 05684 05685 /* Setup audio port number */ 05686 if (p->rtp && sin.sin_port) { 05687 ast_rtp_set_peer(p->rtp, &sin); 05688 if (debug) 05689 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05690 } 05691 05692 /* Setup video port number */ 05693 if (p->vrtp && vsin.sin_port) { 05694 ast_rtp_set_peer(p->vrtp, &vsin); 05695 if (debug) 05696 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 05697 } 05698 05699 /* Ok, we're going with this offer */ 05700 if (option_debug > 1) { 05701 char buf[SIPBUFSIZE]; 05702 ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability)); 05703 } 05704 05705 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 05706 return 0; 05707 05708 if (option_debug > 3) 05709 ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n"); 05710 05711 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05712 if (debug) { 05713 char s1[SIPBUFSIZE], s2[SIPBUFSIZE]; 05714 ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 05715 ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability), 05716 ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats)); 05717 } 05718 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); 05719 ast_set_read_format(p->owner, p->owner->readformat); 05720 ast_set_write_format(p->owner, p->owner->writeformat); 05721 } 05722 05723 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 05724 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 05725 /* Activate a re-invite */ 05726 ast_queue_frame(p->owner, &ast_null_frame); 05727 } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { 05728 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 05729 S_OR(p->mohsuggest, NULL), 05730 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 05731 if (sendonly) 05732 ast_rtp_stop(p->rtp); 05733 /* RTCP needs to go ahead, even if we're on hold!!! */ 05734 /* Activate a re-invite */ 05735 ast_queue_frame(p->owner, &ast_null_frame); 05736 } 05737 05738 /* Manager Hold and Unhold events must be generated, if necessary */ 05739 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) 05740 change_hold_state(p, req, FALSE, sendonly); 05741 else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) 05742 change_hold_state(p, req, TRUE, sendonly); 05743 return 0; 05744 }
static int queue_request | ( | struct sip_pvt * | p, | |
const struct sip_request * | req | |||
) | [static] |
Definition at line 16080 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, ast_sched_add(), copy_request(), sip_request::next, sip_pvt::request_queue, sip_pvt::request_queue_sched_id, sched, and scheduler_process_request_queue().
Referenced by sipsock_read().
16081 { 16082 struct sip_request *newreq; 16083 16084 if (!(newreq = ast_calloc(1, sizeof(*newreq)))) { 16085 return -1; 16086 } 16087 16088 copy_request(newreq, req); 16089 AST_LIST_INSERT_TAIL(&p->request_queue, newreq, next); 16090 if (p->request_queue_sched_id == -1) { 16091 p->request_queue_sched_id = ast_sched_add(sched, 10, scheduler_process_request_queue, p); 16092 } 16093 16094 return 0; 16095 }
static struct sip_peer * realtime_peer | ( | const char * | newpeername, | |
struct sockaddr_in * | sin, | |||
int | devstate_only | |||
) | [static] |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
Definition at line 2551 of file chan_sip.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), sip_request::flags, hp, ast_variable::name, ast_variable::next, ast_variable::value, and var.
02552 { 02553 struct sip_peer *peer=NULL; 02554 struct ast_variable *var = NULL; 02555 struct ast_config *peerlist = NULL; 02556 struct ast_variable *tmp; 02557 struct ast_flags flags = {0}; 02558 const char *iabuf = NULL; 02559 char portstring[6]; /*up to five digits plus null terminator*/ 02560 const char *insecure; 02561 char *cat = NULL; 02562 unsigned short portnum; 02563 02564 /* First check on peer name */ 02565 if (newpeername) { 02566 var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL); 02567 if (!var && sin) 02568 var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02569 if (!var) { 02570 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 02571 /*!\note 02572 * If this one loaded something, then we need to ensure that the host 02573 * field matched. The only reason why we can't have this as a criteria 02574 * is because we only have the IP address and the host field might be 02575 * set as a name (and the reverse PTR might not match). 02576 */ 02577 if (var && sin) { 02578 for (tmp = var; tmp; tmp = tmp->next) { 02579 if (!strcasecmp(tmp->name, "host")) { 02580 struct hostent *hp; 02581 struct ast_hostent ahp; 02582 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02583 /* No match */ 02584 ast_variables_destroy(var); 02585 var = NULL; 02586 } 02587 break; 02588 } 02589 } 02590 } 02591 } 02592 } 02593 02594 if (!var && sin) { /* Then check on IP address */ 02595 iabuf = ast_inet_ntoa(sin->sin_addr); 02596 portnum = ntohs(sin->sin_port); 02597 sprintf(portstring, "%d", portnum); 02598 var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */ 02599 if (!var) 02600 var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL); /* Then check for registered hosts */ 02601 if (!var) { 02602 peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/ 02603 if(peerlist){ 02604 while((cat = ast_category_browse(peerlist, cat))) 02605 { 02606 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02607 set_insecure_flags(&flags, insecure, -1); 02608 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02609 var = ast_category_root(peerlist, cat); 02610 break; 02611 } 02612 } 02613 } 02614 if(!var) { 02615 ast_config_destroy(peerlist); 02616 peerlist = NULL; /*for safety's sake*/ 02617 cat = NULL; 02618 peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/ 02619 if(peerlist) { 02620 while((cat = ast_category_browse(peerlist, cat))) 02621 { 02622 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02623 set_insecure_flags(&flags, insecure, -1); 02624 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02625 var = ast_category_root(peerlist, cat); 02626 break; 02627 } 02628 } 02629 } 02630 } 02631 } 02632 } 02633 02634 if (!var) { 02635 if(peerlist) 02636 ast_config_destroy(peerlist); 02637 return NULL; 02638 } 02639 02640 for (tmp = var; tmp; tmp = tmp->next) { 02641 /* If this is type=user, then skip this object. */ 02642 if (!strcasecmp(tmp->name, "type") && 02643 !strcasecmp(tmp->value, "user")) { 02644 ast_variables_destroy(var); 02645 return NULL; 02646 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 02647 newpeername = tmp->value; 02648 } 02649 } 02650 02651 if (!newpeername) { /* Did not find peer in realtime */ 02652 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); 02653 if(peerlist) 02654 ast_config_destroy(peerlist); 02655 else 02656 ast_variables_destroy(var); 02657 return NULL; 02658 } 02659 02660 /* Peer found in realtime, now build it in memory */ 02661 peer = build_peer(newpeername, var, NULL, 1); 02662 if (!peer) { 02663 if(peerlist) 02664 ast_config_destroy(peerlist); 02665 else 02666 ast_variables_destroy(var); 02667 return NULL; 02668 } 02669 02670 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) { 02671 /* Cache peer */ 02672 ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 02673 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 02674 if (!AST_SCHED_DEL(sched, peer->expire)) { 02675 struct sip_peer *peer_ptr = peer; 02676 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02677 } 02678 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, ASTOBJ_REF(peer)); 02679 if (peer->expire == -1) { 02680 struct sip_peer *peer_ptr = peer; 02681 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02682 } 02683 } 02684 ASTOBJ_CONTAINER_LINK(&peerl,peer); 02685 } 02686 ast_set_flag(&peer->flags[0], SIP_REALTIME); 02687 if(peerlist) 02688 ast_config_destroy(peerlist); 02689 else 02690 ast_variables_destroy(var); 02691 return peer; 02692 }
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 2437 of file chan_sip.c.
References ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, ast_update_realtime(), global_flags, ipaddr, and SIP_PAGE2_RTSAVE_SYSNAME.
02438 { 02439 char port[10]; 02440 char ipaddr[INET_ADDRSTRLEN]; 02441 char regseconds[20]; 02442 02443 char *sysname = ast_config_AST_SYSTEM_NAME; 02444 char *syslabel = NULL; 02445 02446 time_t nowtime = time(NULL) + expirey; 02447 const char *fc = fullcontact ? "fullcontact" : NULL; 02448 02449 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 02450 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 02451 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02452 02453 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 02454 sysname = NULL; 02455 else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME)) 02456 syslabel = "regserver"; 02457 02458 if (fc) 02459 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02460 "port", port, "regseconds", regseconds, 02461 "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */ 02462 else 02463 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02464 "port", port, "regseconds", regseconds, 02465 "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */ 02466 }
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 2742 of file chan_sip.c.
References ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, ast_variable::value, and var.
02743 { 02744 struct ast_variable *var; 02745 struct ast_variable *tmp; 02746 struct sip_user *user = NULL; 02747 02748 var = ast_load_realtime("sipusers", "name", username, NULL); 02749 02750 if (!var) 02751 return NULL; 02752 02753 for (tmp = var; tmp; tmp = tmp->next) { 02754 if (!strcasecmp(tmp->name, "type") && 02755 !strcasecmp(tmp->value, "peer")) { 02756 ast_variables_destroy(var); 02757 return NULL; 02758 } 02759 } 02760 02761 user = build_user(username, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02762 02763 if (!user) { /* No user found */ 02764 ast_variables_destroy(var); 02765 return NULL; 02766 } 02767 02768 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02769 ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02770 suserobjs++; 02771 ASTOBJ_CONTAINER_LINK(&userl,user); 02772 } else { 02773 /* Move counter from s to r... */ 02774 suserobjs--; 02775 ruserobjs++; 02776 } 02777 ast_set_flag(&user->flags[0], SIP_REALTIME); 02778 ast_variables_destroy(var); 02779 return user; 02780 }
static void receive_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 9952 of file chan_sip.c.
References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose(), sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, f, get_header(), get_msg_text(), sip_pvt::owner, sip_debug_test_pvt(), sip_scheddestroy(), and transmit_response().
Referenced by handle_request_message().
09953 { 09954 char buf[1024]; 09955 struct ast_frame f; 09956 const char *content_type = get_header(req, "Content-Type"); 09957 09958 if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */ 09959 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 09960 if (!p->owner) 09961 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09962 return; 09963 } 09964 09965 if (get_msg_text(buf, sizeof(buf), req)) { 09966 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 09967 transmit_response(p, "202 Accepted", req); 09968 if (!p->owner) 09969 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09970 return; 09971 } 09972 09973 if (p->owner) { 09974 if (sip_debug_test_pvt(p)) 09975 ast_verbose("Message received: '%s'\n", buf); 09976 memset(&f, 0, sizeof(f)); 09977 f.frametype = AST_FRAME_TEXT; 09978 f.subclass = 0; 09979 f.offset = 0; 09980 f.data = buf; 09981 f.datalen = strlen(buf); 09982 ast_queue_frame(p->owner, &f); 09983 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 09984 } else { /* Message outside of a call, we do not support that */ 09985 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); 09986 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 09987 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09988 } 09989 return; 09990 }
static char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 1649 of file chan_sip.c.
References referstatusstrings, and text.
Referenced by __sip_show_channels().
01650 { 01651 int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0])); 01652 int x; 01653 01654 for (x = 0; x < i; x++) { 01655 if (referstatusstrings[x].status == rstatus) 01656 return (char *) referstatusstrings[x].text; 01657 } 01658 return ""; 01659 }
static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 8135 of file chan_sip.c.
References sip_peer::addr, ast_copy_string(), ast_db_get(), ast_inet_ntoa(), ast_log(), ast_random(), ast_sched_add(), AST_SCHED_DEL, ast_test_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::expire, expire_register(), sip_peer::flags, sip_peer::fullcontact, LOG_DEBUG, sip_peer::name, option_debug, sip_peer::pokeexpire, register_peer_exten(), sched, sip_destroy_peer(), SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, siptcpsock, TRUE, sip_peer::username, and username.
08136 { 08137 char data[256]; 08138 struct in_addr in; 08139 int expiry; 08140 int port; 08141 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 08142 08143 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08144 return; 08145 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 08146 return; 08147 08148 scan = data; 08149 addr = strsep(&scan, ":"); 08150 port_str = strsep(&scan, ":"); 08151 expiry_str = strsep(&scan, ":"); 08152 username = strsep(&scan, ":"); 08153 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 08154 08155 if (!inet_aton(addr, &in)) 08156 return; 08157 08158 if (port_str) 08159 port = atoi(port_str); 08160 else 08161 return; 08162 08163 if (expiry_str) 08164 expiry = atoi(expiry_str); 08165 else 08166 return; 08167 08168 if (username) 08169 ast_copy_string(peer->username, username, sizeof(peer->username)); 08170 if (contact) 08171 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 08172 08173 if (option_debug > 1) 08174 ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 08175 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 08176 08177 memset(&peer->addr, 0, sizeof(peer->addr)); 08178 peer->addr.sin_family = AF_INET; 08179 peer->addr.sin_addr = in; 08180 peer->addr.sin_port = htons(port); 08181 if ((sipsock < 0) || (siptcpsock < 0)){ 08182 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 08183 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 08184 struct sip_peer *peer_ptr = peer; 08185 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08186 } 08187 peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, ASTOBJ_REF(peer)); 08188 if (peer->pokeexpire == -1) { 08189 struct sip_peer *peer_ptr = peer; 08190 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08191 } 08192 } else 08193 sip_poke_peer(peer); 08194 if (!AST_SCHED_DEL(sched, peer->expire)) { 08195 struct sip_peer *peer_ptr = peer; 08196 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08197 } 08198 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08199 if (peer->expire == -1) { 08200 struct sip_peer *peer_ptr = peer; 08201 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08202 } 08203 register_peer_exten(peer, TRUE); 08204 }
static void register_peer_exten | ( | struct sip_peer * | peer, | |
int | onoff | |||
) | [static] |
Automatically add peer extension to dial plan.
Definition at line 2469 of file chan_sip.c.
References ast_add_extension(), ast_context_find(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free, ast_log(), ast_strdup, ast_strlen_zero(), context, ext, LOG_WARNING, sip_peer::name, sip_peer::regexten, and S_OR.
02470 { 02471 char multi[256]; 02472 char *stringp, *ext, *context; 02473 02474 /* XXX note that global_regcontext is both a global 'enable' flag and 02475 * the name of the global regexten context, if not specified 02476 * individually. 02477 */ 02478 if (ast_strlen_zero(global_regcontext)) 02479 return; 02480 02481 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 02482 stringp = multi; 02483 while ((ext = strsep(&stringp, "&"))) { 02484 if ((context = strchr(ext, '@'))) { 02485 *context++ = '\0'; /* split ext@context */ 02486 if (!ast_context_find(context)) { 02487 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 02488 continue; 02489 } 02490 } else { 02491 context = global_regcontext; 02492 } 02493 if (onoff) { 02494 if (!ast_exists_extension(NULL, context, ext, 1, NULL)) { 02495 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 02496 ast_strdup(peer->name), ast_free, "SIP"); 02497 } 02498 } else { 02499 ast_context_remove_extension(context, ext, 1, NULL); 02500 } 02501 } 02502 }
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 8858 of file chan_sip.c.
References ast_apply_ha(), ast_copy_flags, ast_copy_string(), ast_device_state_changed(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_rtp_codec_setpref(), ast_string_field_set, ast_test_flag, ast_uri_decode(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, AUTH_ACL_FAILED, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, sip_peer::autoframing, sip_pvt::autoframing, build_contact(), check_auth(), check_sip_domain(), EVENT_FLAG_SYSTEM, exten, find_peer(), sip_pvt::flags, sip_peer::flags, get_header(), get_in_brackets(), sip_peer::ha, sip_pvt::initreq, sip_peer::lastmsgssent, LOG_ERROR, LOG_NOTICE, manager_event(), sip_peer::md5secret, sip_peer::name, name, parse_register_contact(), PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, peerl, sip_peer::prefs, sip_pvt::rtp, sip_peer::secret, sip_cancel_destroy(), sip_destroy_peer(), SIP_NAT, SIP_PAGE2_DYNAMIC, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_PKT_IGNORE, SIP_REGISTER, t, temp_peer(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), update_peer(), and XMIT_UNRELIABLE.
08860 { 08861 enum check_auth_result res = AUTH_NOT_FOUND; 08862 struct sip_peer *peer; 08863 char tmp[256]; 08864 char *name, *c; 08865 char *t; 08866 char *domain; 08867 08868 /* Terminate URI */ 08869 t = uri; 08870 while(*t && (*t > 32) && (*t != ';')) 08871 t++; 08872 *t = '\0'; 08873 08874 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 08875 if (pedanticsipchecking) 08876 ast_uri_decode(tmp); 08877 08878 c = get_in_brackets(tmp); 08879 c = strsep(&c, ";"); /* Ditch ;user=phone */ 08880 08881 if (!strncasecmp(c, "sip:", 4)) { 08882 name = c + 4; 08883 } else { 08884 name = c; 08885 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 08886 } 08887 08888 /* Strip off the domain name */ 08889 if ((c = strchr(name, '@'))) { 08890 *c++ = '\0'; 08891 domain = c; 08892 if ((c = strchr(domain, ':'))) /* Remove :port */ 08893 *c = '\0'; 08894 if (!AST_LIST_EMPTY(&domain_list)) { 08895 if (!check_sip_domain(domain, NULL, 0)) { 08896 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 08897 return AUTH_UNKNOWN_DOMAIN; 08898 } 08899 } 08900 } 08901 08902 ast_string_field_set(p, exten, name); 08903 build_contact(p); 08904 peer = find_peer(name, NULL, 1, 0); 08905 if (!(peer && ast_apply_ha(peer->ha, sin))) { 08906 /* Peer fails ACL check */ 08907 if (peer) { 08908 ASTOBJ_UNREF(peer, sip_destroy_peer); 08909 res = AUTH_ACL_FAILED; 08910 } else 08911 res = AUTH_NOT_FOUND; 08912 } 08913 if (peer) { 08914 /* Set Frame packetization */ 08915 if (p->rtp) { 08916 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 08917 p->autoframing = peer->autoframing; 08918 } 08919 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 08920 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 08921 res = AUTH_PEER_NOT_DYNAMIC; 08922 } else { 08923 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 08924 transmit_response(p, "100 Trying", req); 08925 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { 08926 if (sip_cancel_destroy(p)) 08927 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08928 08929 /* We have a succesful registration attemp with proper authentication, 08930 now, update the peer */ 08931 switch (parse_register_contact(p, peer, req)) { 08932 case PARSE_REGISTER_FAILED: 08933 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08934 transmit_response_with_date(p, "400 Bad Request", req); 08935 peer->lastmsgssent = -1; 08936 res = 0; 08937 break; 08938 case PARSE_REGISTER_QUERY: 08939 transmit_response_with_date(p, "200 OK", req); 08940 peer->lastmsgssent = -1; 08941 res = 0; 08942 break; 08943 case PARSE_REGISTER_UPDATE: 08944 update_peer(peer, p->expiry); 08945 /* Say OK and ask subsystem to retransmit msg counter */ 08946 transmit_response_with_date(p, "200 OK", req); 08947 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 08948 peer->lastmsgssent = -1; 08949 res = 0; 08950 break; 08951 } 08952 } 08953 } 08954 } 08955 if (!peer && autocreatepeer) { 08956 /* Create peer if we have autocreate mode enabled */ 08957 peer = temp_peer(name); 08958 if (peer) { 08959 ASTOBJ_CONTAINER_LINK(&peerl, peer); 08960 if (sip_cancel_destroy(p)) 08961 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08962 switch (parse_register_contact(p, peer, req)) { 08963 case PARSE_REGISTER_FAILED: 08964 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08965 transmit_response_with_date(p, "400 Bad Request", req); 08966 peer->lastmsgssent = -1; 08967 res = 0; 08968 break; 08969 case PARSE_REGISTER_QUERY: 08970 transmit_response_with_date(p, "200 OK", req); 08971 peer->lastmsgssent = -1; 08972 res = 0; 08973 break; 08974 case PARSE_REGISTER_UPDATE: 08975 /* Say OK and ask subsystem to retransmit msg counter */ 08976 transmit_response_with_date(p, "200 OK", req); 08977 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08978 peer->lastmsgssent = -1; 08979 res = 0; 08980 break; 08981 } 08982 } 08983 } 08984 if (!res) { 08985 ast_device_state_changed("SIP/%s", peer->name); 08986 } 08987 if (res < 0) { 08988 switch (res) { 08989 case AUTH_SECRET_FAILED: 08990 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 08991 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08992 break; 08993 case AUTH_USERNAME_MISMATCH: 08994 /* Username and digest username does not match. 08995 Asterisk uses the From: username for authentication. We need the 08996 users to use the same authentication user name until we support 08997 proper authentication by digest auth name */ 08998 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 08999 break; 09000 case AUTH_NOT_FOUND: 09001 case AUTH_PEER_NOT_DYNAMIC: 09002 case AUTH_ACL_FAILED: 09003 if (global_alwaysauthreject) { 09004 transmit_fake_auth_response(p, &p->initreq, 1); 09005 } else { 09006 /* URI not found */ 09007 if (res == AUTH_PEER_NOT_DYNAMIC) 09008 transmit_response(p, "403 Forbidden", &p->initreq); 09009 else 09010 transmit_response(p, "404 Not found", &p->initreq); 09011 } 09012 break; 09013 default: 09014 break; 09015 } 09016 } 09017 if (peer) 09018 ASTOBJ_UNREF(peer, sip_destroy_peer); 09019 09020 return res; 09021 }
static char * regstate2str | ( | enum sipregistrystate | regstate | ) | const [static] |
Convert registration state status to string.
Definition at line 7608 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.
07609 { 07610 switch(regstate) { 07611 case REG_STATE_FAILED: 07612 return "Failed"; 07613 case REG_STATE_UNREGISTERED: 07614 return "Unregistered"; 07615 case REG_STATE_REGSENT: 07616 return "Request Sent"; 07617 case REG_STATE_AUTHSENT: 07618 return "Auth. Sent"; 07619 case REG_STATE_REGISTERED: 07620 return "Registered"; 07621 case REG_STATE_REJECTED: 07622 return "Rejected"; 07623 case REG_STATE_TIMEOUT: 07624 return "Timeout"; 07625 case REG_STATE_NOAUTH: 07626 return "No Authentication"; 07627 default: 07628 return "Unknown"; 07629 } 07630 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 18794 of file chan_sip.c.
References sip_reload().
18795 { 18796 return sip_reload(0, 0, NULL); 18797 }
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 17630 of file chan_sip.c.
References ahp, ast_config_load(), ast_free_ha(), ast_log(), AST_MAX_CONTEXT, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, authl, bindaddr, clear_realm_authentication(), clear_sip_domains(), context, FALSE, global_contact_ha, hp, LOG_DEBUG, LOG_NOTICE, option_debug, regl, and sip_destroy().
17631 { 17632 struct ast_config *cfg, *ucfg; 17633 struct ast_variable *v; 17634 struct sip_peer *peer; 17635 struct sip_user *user; 17636 struct ast_hostent ahp; 17637 char *cat, *stringp, *context, *oldregcontext; 17638 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 17639 struct hostent *hp; 17640 int format; 17641 struct ast_flags dummy[2]; 17642 int auto_sip_domains = FALSE; 17643 struct sockaddr_in old_bindaddr = bindaddr; 17644 int registry_count = 0, peer_count = 0, user_count = 0; 17645 unsigned int temp_tos = 0; 17646 struct ast_flags debugflag = {0}; 17647 17648 cfg = ast_config_load(config); 17649 17650 /* We *must* have a config file otherwise stop immediately */ 17651 if (!cfg) { 17652 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 17653 return -1; 17654 } 17655 17656 if (option_debug > 3) 17657 ast_log(LOG_DEBUG, "--------------- SIP reload started\n"); 17658 17659 clear_realm_authentication(authl); 17660 clear_sip_domains(); 17661 authl = NULL; 17662 17663 ast_free_ha(global_contact_ha); 17664 global_contact_ha = NULL; 17665 17666 /* First, destroy all outstanding registry calls */ 17667 /* This is needed, since otherwise active registry entries will not be destroyed */ 17668 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17669 ASTOBJ_RDLOCK(iterator); 17670 if (iterator->call) { 17671 if (option_debug > 2) 17672 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 17673 /* This will also remove references to the registry */ 17674 sip_destroy(iterator->call); 17675 } 17676 ASTOBJ_UNLOCK(iterator); 17677 17678 } while(0)); 17679 17680 /* Then, actually destroy users and registry */ 17681 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 17682 if (option_debug > 3) 17683 ast_log(LOG_DEBUG, "--------------- Done destroying user list\n"); 17684 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 17685 if (option_debug > 3) 17686 ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n"); 17687 ASTOBJ_CONTAINER_MARKALL(&peerl); 17688 17689 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 17690 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 17691 oldregcontext = oldcontexts; 17692 17693 /* Clear all flags before setting default values */ 17694 /* Preserve debugging settings for console */ 17695 ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 17696 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 17697 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 17698 ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE); 17699 17700 /* Reset IP addresses */ 17701 memset(&bindaddr, 0, sizeof(bindaddr)); 17702 ast_free_ha(localaddr); 17703 memset(&localaddr, 0, sizeof(localaddr)); 17704 memset(&externip, 0, sizeof(externip)); 17705 memset(&default_prefs, 0 , sizeof(default_prefs)); 17706 outboundproxyip.sin_port = htons(STANDARD_SIP_PORT); 17707 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 17708 ourport = STANDARD_SIP_PORT; 17709 srvlookup = DEFAULT_SRVLOOKUP; 17710 global_tos_sip = DEFAULT_TOS_SIP; 17711 global_tos_audio = DEFAULT_TOS_AUDIO; 17712 global_tos_video = DEFAULT_TOS_VIDEO; 17713 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 17714 externexpire = 0; /* Expiration for DNS re-issuing */ 17715 externrefresh = 10; 17716 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 17717 17718 /* Reset channel settings to default before re-configuring */ 17719 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 17720 global_regcontext[0] = '\0'; 17721 expiry = DEFAULT_EXPIRY; 17722 global_notifyringing = DEFAULT_NOTIFYRINGING; 17723 global_limitonpeers = FALSE; 17724 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 17725 global_notifyhold = FALSE; 17726 global_alwaysauthreject = 0; 17727 global_allowsubscribe = FALSE; 17728 ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent)); 17729 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 17730 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) 17731 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 17732 else 17733 ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm)); 17734 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 17735 compactheaders = DEFAULT_COMPACTHEADERS; 17736 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 17737 global_regattempts_max = 0; 17738 pedanticsipchecking = DEFAULT_PEDANTIC; 17739 global_mwitime = DEFAULT_MWITIME; 17740 autocreatepeer = DEFAULT_AUTOCREATEPEER; 17741 global_autoframing = 0; 17742 global_allowguest = DEFAULT_ALLOWGUEST; 17743 global_rtptimeout = 0; 17744 global_rtpholdtimeout = 0; 17745 global_rtpkeepalive = 0; 17746 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 17747 global_rtautoclear = 120; 17748 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 17749 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 17750 ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE); 17751 17752 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 17753 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 17754 default_subscribecontext[0] = '\0'; 17755 default_language[0] = '\0'; 17756 default_fromdomain[0] = '\0'; 17757 default_qualify = DEFAULT_QUALIFY; 17758 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 17759 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 17760 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 17761 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 17762 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 17763 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 17764 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 17765 17766 /* Debugging settings, always default to off */ 17767 dumphistory = FALSE; 17768 recordhistory = FALSE; 17769 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 17770 17771 /* Misc settings for the channel */ 17772 global_relaxdtmf = FALSE; 17773 global_callevents = FALSE; 17774 global_t1min = DEFAULT_T1MIN; 17775 17776 global_matchexterniplocally = FALSE; 17777 17778 /* Copy the default jb config over global_jbconf */ 17779 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 17780 17781 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 17782 17783 /* Read the [general] config section of sip.conf (or from realtime config) */ 17784 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 17785 if (handle_common_options(&global_flags[0], &dummy[0], v)) 17786 continue; 17787 /* handle jb conf */ 17788 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 17789 continue; 17790 17791 /* Create the interface list */ 17792 if (!strcasecmp(v->name, "context")) { 17793 ast_copy_string(default_context, v->value, sizeof(default_context)); 17794 } else if (!strcasecmp(v->name, "subscribecontext")) { 17795 ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext)); 17796 } else if (!strcasecmp(v->name, "allowguest")) { 17797 global_allowguest = ast_true(v->value) ? 1 : 0; 17798 } else if (!strcasecmp(v->name, "realm")) { 17799 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 17800 } else if (!strcasecmp(v->name, "useragent")) { 17801 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 17802 if (option_debug) 17803 ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 17804 } else if (!strcasecmp(v->name, "allowtransfer")) { 17805 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17806 } else if (!strcasecmp(v->name, "rtcachefriends")) { 17807 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 17808 } else if (!strcasecmp(v->name, "rtsavesysname")) { 17809 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME); 17810 } else if (!strcasecmp(v->name, "rtupdate")) { 17811 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE); 17812 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 17813 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 17814 } else if (!strcasecmp(v->name, "t1min")) { 17815 global_t1min = atoi(v->value); 17816 } else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) { 17817 global_dynamic_exclude_static = ast_true(v->value); 17818 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 17819 global_contact_ha = ast_append_ha(v->name + 7, v->value, global_contact_ha); 17820 } else if (!strcasecmp(v->name, "rtautoclear")) { 17821 int i = atoi(v->value); 17822 if (i > 0) 17823 global_rtautoclear = i; 17824 else 17825 i = 0; 17826 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 17827 } else if (!strcasecmp(v->name, "usereqphone")) { 17828 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 17829 } else if (!strcasecmp(v->name, "relaxdtmf")) { 17830 global_relaxdtmf = ast_true(v->value); 17831 } else if (!strcasecmp(v->name, "checkmwi")) { 17832 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 17833 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 17834 global_mwitime = DEFAULT_MWITIME; 17835 } 17836 } else if (!strcasecmp(v->name, "vmexten")) { 17837 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 17838 } else if (!strcasecmp(v->name, "rtptimeout")) { 17839 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 17840 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17841 global_rtptimeout = 0; 17842 } 17843 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 17844 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 17845 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17846 global_rtpholdtimeout = 0; 17847 } 17848 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 17849 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 17850 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 17851 global_rtpkeepalive = 0; 17852 } 17853 } else if (!strcasecmp(v->name, "compactheaders")) { 17854 compactheaders = ast_true(v->value); 17855 } else if (!strcasecmp(v->name, "notifymimetype")) { 17856 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 17857 } else if (!strncasecmp(v->name, "limitonpeer", 11)) { 17858 global_limitonpeers = ast_true(v->value); 17859 } else if (!strcasecmp(v->name, "directrtpsetup")) { 17860 global_directrtpsetup = ast_true(v->value); 17861 } else if (!strcasecmp(v->name, "notifyringing")) { 17862 global_notifyringing = ast_true(v->value); 17863 } else if (!strcasecmp(v->name, "notifyhold")) { 17864 global_notifyhold = ast_true(v->value); 17865 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 17866 global_alwaysauthreject = ast_true(v->value); 17867 } else if (!strcasecmp(v->name, "mohinterpret") 17868 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17869 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 17870 } else if (!strcasecmp(v->name, "mohsuggest")) { 17871 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 17872 } else if (!strcasecmp(v->name, "language")) { 17873 ast_copy_string(default_language, v->value, sizeof(default_language)); 17874 } else if (!strcasecmp(v->name, "regcontext")) { 17875 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 17876 stringp = newcontexts; 17877 /* Let's remove any contexts that are no longer defined in regcontext */ 17878 cleanup_stale_contexts(stringp, oldregcontext); 17879 /* Create contexts if they don't exist already */ 17880 while ((context = strsep(&stringp, "&"))) { 17881 if (!ast_context_find(context)) 17882 ast_context_create(NULL, context,"SIP"); 17883 } 17884 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 17885 } else if (!strcasecmp(v->name, "callerid")) { 17886 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 17887 } else if (!strcasecmp(v->name, "fromdomain")) { 17888 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 17889 } else if (!strcasecmp(v->name, "outboundproxy")) { 17890 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 17891 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 17892 } else if (!strcasecmp(v->name, "outboundproxyport")) { 17893 /* Port needs to be after IP */ 17894 sscanf(v->value, "%d", &format); 17895 outboundproxyip.sin_port = htons(format); 17896 } else if (!strcasecmp(v->name, "autocreatepeer")) { 17897 autocreatepeer = ast_true(v->value); 17898 } else if (!strcasecmp(v->name, "srvlookup")) { 17899 srvlookup = ast_true(v->value); 17900 } else if (!strcasecmp(v->name, "pedantic")) { 17901 pedanticsipchecking = ast_true(v->value); 17902 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 17903 max_expiry = atoi(v->value); 17904 if (max_expiry < 1) 17905 max_expiry = DEFAULT_MAX_EXPIRY; 17906 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 17907 min_expiry = atoi(v->value); 17908 if (min_expiry < 1) 17909 min_expiry = DEFAULT_MIN_EXPIRY; 17910 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 17911 default_expiry = atoi(v->value); 17912 if (default_expiry < 1) 17913 default_expiry = DEFAULT_DEFAULT_EXPIRY; 17914 } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */ 17915 if (ast_true(v->value)) 17916 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 17917 } else if (!strcasecmp(v->name, "dumphistory")) { 17918 dumphistory = ast_true(v->value); 17919 } else if (!strcasecmp(v->name, "recordhistory")) { 17920 recordhistory = ast_true(v->value); 17921 } else if (!strcasecmp(v->name, "registertimeout")) { 17922 global_reg_timeout = atoi(v->value); 17923 if (global_reg_timeout < 1) 17924 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 17925 } else if (!strcasecmp(v->name, "registerattempts")) { 17926 global_regattempts_max = atoi(v->value); 17927 } else if (!strcasecmp(v->name, "bindaddr")) { 17928 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 17929 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 17930 } else { 17931 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 17932 } 17933 } else if (!strcasecmp(v->name, "localnet")) { 17934 struct ast_ha *na; 17935 if (!(na = ast_append_ha("d", v->value, localaddr))) 17936 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 17937 else 17938 localaddr = na; 17939 } else if (!strcasecmp(v->name, "localmask")) { 17940 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 17941 } else if (!strcasecmp(v->name, "externip")) { 17942 if (!(hp = ast_gethostbyname(v->value, &ahp))) 17943 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 17944 else 17945 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 17946 externexpire = 0; 17947 } else if (!strcasecmp(v->name, "externhost")) { 17948 ast_copy_string(externhost, v->value, sizeof(externhost)); 17949 if (!(hp = ast_gethostbyname(externhost, &ahp))) 17950 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 17951 else 17952 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 17953 externexpire = time(NULL); 17954 } else if (!strcasecmp(v->name, "externrefresh")) { 17955 if (sscanf(v->value, "%d", &externrefresh) != 1) { 17956 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 17957 externrefresh = 10; 17958 } 17959 } else if (!strcasecmp(v->name, "allow")) { 17960 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1); 17961 } else if (!strcasecmp(v->name, "disallow")) { 17962 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0); 17963 } else if (!strcasecmp(v->name, "autoframing")) { 17964 global_autoframing = ast_true(v->value); 17965 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 17966 allow_external_domains = ast_true(v->value); 17967 } else if (!strcasecmp(v->name, "autodomain")) { 17968 auto_sip_domains = ast_true(v->value); 17969 } else if (!strcasecmp(v->name, "domain")) { 17970 char *domain = ast_strdupa(v->value); 17971 char *context = strchr(domain, ','); 17972 17973 if (context) 17974 *context++ = '\0'; 17975 17976 if (option_debug && ast_strlen_zero(context)) 17977 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 17978 if (ast_strlen_zero(domain)) 17979 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 17980 else 17981 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 17982 } else if (!strcasecmp(v->name, "register")) { 17983 if (sip_register(v->value, v->lineno) == 0) 17984 registry_count++; 17985 } else if (!strcasecmp(v->name, "tos")) { 17986 if (!ast_str2tos(v->value, &temp_tos)) { 17987 global_tos_sip = temp_tos; 17988 global_tos_audio = temp_tos; 17989 global_tos_video = temp_tos; 17990 ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno); 17991 } else 17992 ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno); 17993 } else if (!strcasecmp(v->name, "tos_sip")) { 17994 if (ast_str2tos(v->value, &global_tos_sip)) 17995 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); 17996 } else if (!strcasecmp(v->name, "tos_audio")) { 17997 if (ast_str2tos(v->value, &global_tos_audio)) 17998 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); 17999 } else if (!strcasecmp(v->name, "tos_video")) { 18000 if (ast_str2tos(v->value, &global_tos_video)) 18001 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); 18002 } else if (!strcasecmp(v->name, "bindport")) { 18003 if (sscanf(v->value, "%d", &ourport) == 1) { 18004 bindaddr.sin_port = htons(ourport); 18005 } else { 18006 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 18007 } 18008 } else if (!strcasecmp(v->name, "qualify")) { 18009 if (!strcasecmp(v->value, "no")) { 18010 default_qualify = 0; 18011 } else if (!strcasecmp(v->value, "yes")) { 18012 default_qualify = DEFAULT_MAXMS; 18013 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 18014 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 18015 default_qualify = 0; 18016 } 18017 } else if (!strcasecmp(v->name, "callevents")) { 18018 global_callevents = ast_true(v->value); 18019 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 18020 default_maxcallbitrate = atoi(v->value); 18021 if (default_maxcallbitrate < 0) 18022 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 18023 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 18024 global_matchexterniplocally = ast_true(v->value); 18025 } 18026 } 18027 18028 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 18029 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 18030 allow_external_domains = 1; 18031 } 18032 18033 /* Build list of authentication to various SIP realms, i.e. service providers */ 18034 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 18035 /* Format for authentication is auth = username:password@realm */ 18036 if (!strcasecmp(v->name, "auth")) 18037 authl = add_realm_authentication(authl, v->value, v->lineno); 18038 } 18039 18040 ucfg = ast_config_load("users.conf"); 18041 if (ucfg) { 18042 struct ast_variable *gen; 18043 int genhassip, genregistersip; 18044 const char *hassip, *registersip; 18045 18046 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 18047 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 18048 gen = ast_variable_browse(ucfg, "general"); 18049 cat = ast_category_browse(ucfg, NULL); 18050 while (cat) { 18051 if (strcasecmp(cat, "general")) { 18052 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 18053 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 18054 if (ast_true(hassip) || (!hassip && genhassip)) { 18055 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 18056 if (user) { 18057 ASTOBJ_CONTAINER_LINK(&userl,user); 18058 ASTOBJ_UNREF(user, sip_destroy_user); 18059 user_count++; 18060 } 18061 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 18062 if (peer) { 18063 ast_device_state_changed("SIP/%s", peer->name); 18064 ASTOBJ_CONTAINER_LINK(&peerl,peer); 18065 ASTOBJ_UNREF(peer, sip_destroy_peer); 18066 peer_count++; 18067 } 18068 } 18069 if (ast_true(registersip) || (!registersip && genregistersip)) { 18070 char tmp[256]; 18071 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 18072 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 18073 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 18074 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 18075 if (!host) 18076 host = ast_variable_retrieve(ucfg, "general", "host"); 18077 if (!username) 18078 username = ast_variable_retrieve(ucfg, "general", "username"); 18079 if (!secret) 18080 secret = ast_variable_retrieve(ucfg, "general", "secret"); 18081 if (!contact) 18082 contact = "s"; 18083 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 18084 if (!ast_strlen_zero(secret)) 18085 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 18086 else 18087 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 18088 if (sip_register(tmp, 0) == 0) 18089 registry_count++; 18090 } 18091 } 18092 } 18093 cat = ast_category_browse(ucfg, cat); 18094 } 18095 ast_config_destroy(ucfg); 18096 } 18097 18098 18099 /* Load peers, users and friends */ 18100 cat = NULL; 18101 while ( (cat = ast_category_browse(cfg, cat)) ) { 18102 const char *utype; 18103 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 18104 continue; 18105 utype = ast_variable_retrieve(cfg, cat, "type"); 18106 if (!utype) { 18107 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 18108 continue; 18109 } else { 18110 int is_user = 0, is_peer = 0; 18111 if (!strcasecmp(utype, "user")) 18112 is_user = 1; 18113 else if (!strcasecmp(utype, "friend")) 18114 is_user = is_peer = 1; 18115 else if (!strcasecmp(utype, "peer")) 18116 is_peer = 1; 18117 else { 18118 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 18119 continue; 18120 } 18121 if (is_user) { 18122 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 18123 if (user) { 18124 ASTOBJ_CONTAINER_LINK(&userl,user); 18125 ASTOBJ_UNREF(user, sip_destroy_user); 18126 user_count++; 18127 } 18128 } 18129 if (is_peer) { 18130 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 18131 if (peer) { 18132 ASTOBJ_CONTAINER_LINK(&peerl,peer); 18133 ASTOBJ_UNREF(peer, sip_destroy_peer); 18134 peer_count++; 18135 } 18136 } 18137 } 18138 } 18139 if (ast_find_ourip(&__ourip, bindaddr)) { 18140 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 18141 ast_config_destroy(cfg); 18142 return 0; 18143 } 18144 if (!ntohs(bindaddr.sin_port)) 18145 bindaddr.sin_port = ntohs(STANDARD_SIP_PORT); 18146 bindaddr.sin_family = AF_INET; 18147 ast_mutex_lock(&netlock); 18148 if (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in))) { 18149 if (sipsock > -1) { 18150 close(sipsock); 18151 sipsock = -1; 18152 } 18153 if (siptcpsock > -1) { 18154 close(siptcpsock); 18155 siptcpsock = -1; 18156 } 18157 } 18158 if (sipsock < 0) { 18159 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 18160 if (sipsock < 0) { 18161 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 18162 } else { 18163 /* Allow SIP clients on the same host to access us: */ 18164 const int reuseFlag = 1; 18165 18166 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 18167 (const char*)&reuseFlag, 18168 sizeof reuseFlag); 18169 18170 ast_enable_packet_fragmentation(sipsock); 18171 18172 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 18173 ast_log(LOG_WARNING, "Failed to bind to UDP %s:%d: %s\n", 18174 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 18175 strerror(errno)); 18176 close(sipsock); 18177 sipsock = -1; 18178 } else { 18179 if (option_verbose > 1) { 18180 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on UDP %s:%d\n", 18181 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 18182 ast_verbose(VERBOSE_PREFIX_2 "Using SIP UDP TOS: %s\n", ast_tos2str(global_tos_sip)); 18183 } 18184 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 18185 ast_log(LOG_WARNING, "Unable to set SIP UDP TOS to %s\n", ast_tos2str(global_tos_sip)); 18186 } 18187 } 18188 } 18189 if (siptcpsock < 0) { 18190 siptcpsock = socket(AF_INET, SOCK_STREAM, 0); 18191 if (siptcpsock < 0) { 18192 ast_log(LOG_WARNING, "Unable to create SIP TCP socket: %s\n", strerror(errno)); 18193 } else { 18194 /* Allow SIP clients on the same host to access us: */ 18195 const int reuseFlag = 1; 18196 18197 setsockopt(siptcpsock, SOL_SOCKET, SO_REUSEADDR, 18198 (const char*)&reuseFlag, 18199 sizeof reuseFlag); 18200 18201 ast_enable_packet_fragmentation(sipsock); 18202 18203 if (bind(siptcpsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 18204 ast_log(LOG_WARNING, "Failed to bind to TCP %s:%d: %s\n", 18205 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 18206 strerror(errno)); 18207 close(siptcpsock); 18208 siptcpsock = -1; 18209 } else { 18210 if (listen(siptcpsock, 30) < 0) { 18211 ast_log(LOG_WARNING, "Failed to listen on SIP TCP\n"); 18212 } else { 18213 if (option_verbose > 1) { 18214 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on TCP %s:%d\n", 18215 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 18216 ast_verbose(VERBOSE_PREFIX_2 "Using SIP TCP TOS: %s\n", ast_tos2str(global_tos_sip)); 18217 } 18218 if (setsockopt(siptcpsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 18219 ast_log(LOG_WARNING, "Unable to set SIP TCP TOS to %s\n", ast_tos2str(global_tos_sip)); 18220 } 18221 } 18222 } 18223 } 18224 if ((sipsock < 0) && (siptcpsock <0)) { 18225 ast_config_destroy(cfg); 18226 return -1; 18227 } 18228 ast_mutex_unlock(&netlock); 18229 18230 /* Add default domains - host name, IP address and IP:port */ 18231 /* Only do this if user added any sip domain with "localdomains" */ 18232 /* In order to *not* break backwards compatibility */ 18233 /* Some phones address us at IP only, some with additional port number */ 18234 if (auto_sip_domains) { 18235 char temp[MAXHOSTNAMELEN]; 18236 18237 /* First our default IP address */ 18238 if (bindaddr.sin_addr.s_addr) 18239 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 18240 else 18241 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 18242 18243 /* Our extern IP address, if configured */ 18244 if (externip.sin_addr.s_addr) 18245 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 18246 18247 /* Extern host name (NAT traversal support) */ 18248 if (!ast_strlen_zero(externhost)) 18249 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 18250 18251 /* Our host name */ 18252 if (!gethostname(temp, sizeof(temp))) 18253 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 18254 } 18255 18256 /* Release configuration from memory */ 18257 ast_config_destroy(cfg); 18258 18259 /* Load the list of manual NOTIFY types to support */ 18260 if (notify_types) 18261 ast_config_destroy(notify_types); 18262 notify_types = ast_config_load(notify_config); 18263 18264 /* Done, tell the manager */ 18265 manager_event(EVENT_FLAG_SYSTEM, "ChannelReload", "Channel: SIP\r\nReloadReason: %s\r\nRegistry_Count: %d\r\nPeer_Count: %d\r\nUser_Count: %d\r\n", channelreloadreason2txt(reason), registry_count, peer_count, user_count); 18266 18267 return 0; 18268 }
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 11754 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_skip_blanks(), ast_string_field_index, ast_string_field_index_set, ast_string_field_set, ast_strlen_zero(), build_reply_digest(), sip_pvt::domain, get_header(), keys, sip_registry::nonce, sip_pvt::nonce, sip_registry::noncecount, sip_pvt::noncecount, sip_pvt::opaque, sip_registry::opaque, sip_pvt::qop, sip_registry::qop, sip_pvt::realm, sip_registry::realm, and sip_pvt::registry.
Referenced by do_proxy_auth(), and do_register_auth().
11755 { 11756 char tmp[512]; 11757 char *c; 11758 char oldnonce[256]; 11759 11760 /* table of recognised keywords, and places where they should be copied */ 11761 const struct x { 11762 const char *key; 11763 int field_index; 11764 } *i, keys[] = { 11765 { "realm=", ast_string_field_index(p, realm) }, 11766 { "nonce=", ast_string_field_index(p, nonce) }, 11767 { "opaque=", ast_string_field_index(p, opaque) }, 11768 { "qop=", ast_string_field_index(p, qop) }, 11769 { "domain=", ast_string_field_index(p, domain) }, 11770 { NULL, 0 }, 11771 }; 11772 11773 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 11774 if (ast_strlen_zero(tmp)) 11775 return -1; 11776 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 11777 ast_log(LOG_WARNING, "missing Digest.\n"); 11778 return -1; 11779 } 11780 c = tmp + strlen("Digest "); 11781 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 11782 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 11783 for (i = keys; i->key != NULL; i++) { 11784 char *src, *separator; 11785 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 11786 continue; 11787 /* Found. Skip keyword, take text in quotes or up to the separator. */ 11788 c += strlen(i->key); 11789 if (*c == '"') { 11790 src = ++c; 11791 separator = "\""; 11792 } else { 11793 src = c; 11794 separator = ","; 11795 } 11796 strsep(&c, separator); /* clear separator and move ptr */ 11797 ast_string_field_index_set(p, i->field_index, src); 11798 break; 11799 } 11800 if (i->key == NULL) /* not found, try ',' */ 11801 strsep(&c, ","); 11802 } 11803 /* Reset nonce count */ 11804 if (strcmp(p->nonce, oldnonce)) 11805 p->noncecount = 0; 11806 11807 /* Save auth data for following registrations */ 11808 if (p->registry) { 11809 struct sip_registry *r = p->registry; 11810 11811 if (strcmp(r->nonce, p->nonce)) { 11812 ast_string_field_set(r, realm, p->realm); 11813 ast_string_field_set(r, nonce, p->nonce); 11814 ast_string_field_set(r, domain, p->domain); 11815 ast_string_field_set(r, opaque, p->opaque); 11816 ast_string_field_set(r, qop, p->qop); 11817 r->noncecount = 0; 11818 } 11819 } 11820 return build_reply_digest(p, sipmethod, digest, digest_len); 11821 }
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 6084 of file chan_sip.c.
References add_header(), add_route(), ast_copy_string(), ast_log(), ast_random(), ast_strlen_zero(), ast_test_flag, sip_pvt::branch, build_via(), sip_pvt::callid, copy_header(), DEFAULT_MAX_FORWARDS, FALSE, sip_pvt::flags, get_header(), get_in_brackets(), sip_route::hop, init_req(), sip_pvt::initreq, sip_pvt::invite_branch, sip_pvt::lastmsg, LOG_DEBUG, sip_route::next, sip_pvt::ocseq, sip_pvt::okcontacturi, sip_pvt::our_contact, sip_request::rlPart2, sip_pvt::route, sip_pvt::rpid, set_destination(), SIP_ACK, SIP_BYE, SIP_CANCEL, SIP_MESSAGE, sip_methods, SIP_OUTGOING, sipdebug, sip_pvt::tag, text, cfsip_methods::text, sip_pvt::theirtag, TRUE, sip_pvt::uri, and sip_pvt::via.
06085 { 06086 struct sip_request *orig = &p->initreq; 06087 char stripped[80]; 06088 char tmp[80]; 06089 char newto[256]; 06090 const char *c; 06091 const char *ot, *of; 06092 int is_strict = FALSE; /*!< Strict routing flag */ 06093 06094 memset(req, 0, sizeof(struct sip_request)); 06095 06096 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 06097 06098 if (!seqno) { 06099 p->ocseq++; 06100 seqno = p->ocseq; 06101 } 06102 06103 if (sipmethod == SIP_CANCEL) { 06104 p->branch = p->invite_branch; 06105 build_via(p); 06106 } else if (newbranch) { 06107 p->branch ^= ast_random(); 06108 build_via(p); 06109 } 06110 06111 /* Check for strict or loose router */ 06112 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) { 06113 is_strict = TRUE; 06114 if (sipdebug) 06115 ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid); 06116 } 06117 06118 if (sipmethod == SIP_CANCEL) 06119 c = p->initreq.rlPart2; /* Use original URI */ 06120 else if (sipmethod == SIP_ACK) { 06121 /* Use URI from Contact: in 200 OK (if INVITE) 06122 (we only have the contacturi on INVITEs) */ 06123 if (!ast_strlen_zero(p->okcontacturi)) 06124 c = is_strict ? p->route->hop : p->okcontacturi; 06125 else 06126 c = p->initreq.rlPart2; 06127 } else if (!ast_strlen_zero(p->okcontacturi)) 06128 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 06129 else if (!ast_strlen_zero(p->uri)) 06130 c = p->uri; 06131 else { 06132 char *n; 06133 /* We have no URI, use To: or From: header as URI (depending on direction) */ 06134 ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"), 06135 sizeof(stripped)); 06136 n = get_in_brackets(stripped); 06137 c = strsep(&n, ";"); /* trim ; and beyond */ 06138 } 06139 init_req(req, sipmethod, c); 06140 06141 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 06142 06143 add_header(req, "Via", p->via); 06144 if (p->route) { 06145 set_destination(p, p->route->hop); 06146 add_route(req, is_strict ? p->route->next : p->route); 06147 } 06148 06149 ot = get_header(orig, "To"); 06150 of = get_header(orig, "From"); 06151 06152 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 06153 as our original request, including tag (or presumably lack thereof) */ 06154 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 06155 /* Add the proper tag if we don't have it already. If they have specified 06156 their tag, use it. Otherwise, use our own tag */ 06157 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 06158 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06159 else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06160 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06161 else 06162 snprintf(newto, sizeof(newto), "%s", ot); 06163 ot = newto; 06164 } 06165 06166 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06167 add_header(req, "From", of); 06168 add_header(req, "To", ot); 06169 } else { 06170 add_header(req, "From", ot); 06171 add_header(req, "To", of); 06172 } 06173 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 06174 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 06175 add_header(req, "Contact", p->our_contact); 06176 06177 copy_header(req, orig, "Call-ID"); 06178 add_header(req, "CSeq", tmp); 06179 06180 if (!ast_strlen_zero(global_useragent)) 06181 add_header(req, "User-Agent", global_useragent); 06182 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 06183 06184 if (!ast_strlen_zero(p->rpid)) 06185 add_header(req, "Remote-Party-ID", p->rpid); 06186 06187 return 0; 06188 }
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 6036 of file chan_sip.c.
References add_header(), ALLOWED_METHODS, ast_copy_string(), 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_pvt::our_contact, SIP_OUTGOING, SIP_REGISTER, SIP_SUBSCRIBE, SIPBUFSIZE, SUPPORTED_EXTENSIONS, sip_pvt::tag, and sip_pvt::theirtag.
06037 { 06038 char newto[256]; 06039 const char *ot; 06040 06041 init_resp(resp, msg); 06042 copy_via_headers(p, resp, req, "Via"); 06043 if (msg[0] == '1' || msg[0] == '2') 06044 copy_all_header(resp, req, "Record-Route"); 06045 copy_header(resp, req, "From"); 06046 ot = get_header(req, "To"); 06047 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 06048 /* Add the proper tag if we don't have it already. If they have specified 06049 their tag, use it. Otherwise, use our own tag */ 06050 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06051 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06052 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06053 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06054 else 06055 ast_copy_string(newto, ot, sizeof(newto)); 06056 ot = newto; 06057 } 06058 add_header(resp, "To", ot); 06059 copy_header(resp, req, "Call-ID"); 06060 copy_header(resp, req, "CSeq"); 06061 if (!ast_strlen_zero(global_useragent)) 06062 add_header(resp, "User-Agent", global_useragent); 06063 add_header(resp, "Allow", ALLOWED_METHODS); 06064 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 06065 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 06066 /* For registration responses, we also need expiry and 06067 contact info */ 06068 char tmp[256]; 06069 06070 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 06071 add_header(resp, "Expires", tmp); 06072 if (p->expiry) { /* Only add contact if we have an expiry time */ 06073 char contact[SIPBUFSIZE]; 06074 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 06075 add_header(resp, "Contact", contact); /* Not when we unregister */ 06076 } 06077 } else if (msg[0] != '4' && !ast_strlen_zero(p->our_contact)) { 06078 add_header(resp, "Contact", p->our_contact); 06079 } 06080 return 0; 06081 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 16506 of file chan_sip.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, and monlock.
16507 { 16508 /* If we're supposed to be stopped -- stay stopped */ 16509 if (monitor_thread == AST_PTHREADT_STOP) 16510 return 0; 16511 ast_mutex_lock(&monlock); 16512 if (monitor_thread == pthread_self()) { 16513 ast_mutex_unlock(&monlock); 16514 ast_log(LOG_WARNING, "Cannot kill myself\n"); 16515 return -1; 16516 } 16517 if (monitor_thread != AST_PTHREADT_NULL) { 16518 /* Wake up the thread */ 16519 pthread_kill(monitor_thread, SIGURG); 16520 } else { 16521 /* Start a new monitor */ 16522 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 16523 ast_mutex_unlock(&monlock); 16524 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 16525 return -1; 16526 } 16527 } 16528 ast_mutex_unlock(&monlock); 16529 return 0; 16530 }
static int retrans_pkt | ( | const void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 1932 of file chan_sip.c.
References __sip_xmit(), append_history, AST_CAUSE_NO_USER_RESPONSE, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_hangup(), ast_set_flag, ast_test_flag, ast_verbose(), sip_pvt::callid, sip_pkt::data, DEADLOCK_AVOIDANCE, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, sip_pvt::flags, free, sip_pvt::from, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, MAX_RETRANS, sip_pkt::method, ast_channel::name, sip_pkt::next, option_debug, sip_pvt::owner, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pkt::retrans, sip_pkt::retransid, sip_pkt::seqno, sip_alreadygone(), SIP_BYE, sip_debug_test_pvt(), SIP_INVITE, sip_methods, sip_nat_mode(), SIP_NEEDDESTROY, SIP_OPTIONS, sip_real_dst(), sipdebug, sip_pkt::timer_a, sip_pkt::timer_t1, and XMIT_ERROR.
01933 { 01934 struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL; 01935 int reschedule = DEFAULT_RETRANS; 01936 int xmitres = 0; 01937 01938 /* Lock channel PVT */ 01939 ast_mutex_lock(&pkt->owner->lock); 01940 01941 if (pkt->retrans < MAX_RETRANS) { 01942 pkt->retrans++; 01943 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 01944 if (sipdebug && option_debug > 3) 01945 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); 01946 } else { 01947 int siptimer_a; 01948 01949 if (sipdebug && option_debug > 3) 01950 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 01951 if (!pkt->timer_a) 01952 pkt->timer_a = 2 ; 01953 else 01954 pkt->timer_a = 2 * pkt->timer_a; 01955 01956 /* For non-invites, a maximum of 4 secs */ 01957 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 01958 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 01959 siptimer_a = 4000; 01960 01961 /* Reschedule re-transmit */ 01962 reschedule = siptimer_a; 01963 if (option_debug > 3) 01964 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); 01965 } 01966 01967 if (sip_debug_test_pvt(pkt->owner)) { 01968 const struct sockaddr_in *dst = sip_real_dst(pkt->owner); 01969 ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n", 01970 pkt->retrans, sip_nat_mode(pkt->owner), 01971 ast_inet_ntoa(dst->sin_addr), 01972 ntohs(dst->sin_port), pkt->data); 01973 } 01974 01975 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data); 01976 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 01977 ast_mutex_unlock(&pkt->owner->lock); 01978 if (xmitres == XMIT_ERROR) 01979 ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid); 01980 else 01981 return reschedule; 01982 } 01983 /* Too many retries */ 01984 if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) { 01985 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 01986 ast_log(LOG_WARNING, "Maximum retries exceeded on transmission %s from %s for packet seqno %d (%s %s %s)\n", pkt->owner->callid, pkt->owner->from, pkt->seqno, (ast_test_flag(pkt, FLAG_FATAL)) ? "Critical" : "Non-critical", (ast_test_flag(pkt, FLAG_RESPONSE)) ? "Response: " : "Request: ", sip_methods[pkt->method].text); 01987 } else if ((pkt->method == SIP_OPTIONS) && sipdebug) { 01988 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) -- See doc/sip-retransmit.txt.\n", pkt->owner->callid); 01989 } 01990 if (xmitres == XMIT_ERROR) { 01991 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission of transaction in call id %s \n", pkt->owner->callid); 01992 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01993 } else 01994 append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01995 01996 pkt->retransid = -1; 01997 01998 if (ast_test_flag(pkt, FLAG_FATAL)) { 01999 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 02000 DEADLOCK_AVOIDANCE(&pkt->owner->lock); /* SIP_PVT, not channel */ 02001 } 02002 02003 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 02004 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 02005 02006 if (pkt->owner->owner) { 02007 sip_alreadygone(pkt->owner); 02008 ast_log(LOG_WARNING, "Hanging up call %s from channel %s . No reply to our critical packet after %d retries (see doc/sip-retransmit.txt).\n", pkt->owner->callid, pkt->owner->owner->name, pkt->retrans); 02009 ast_queue_hangup(pkt->owner->owner); 02010 ast_channel_unlock(pkt->owner->owner); 02011 } else { 02012 /* If no channel owner, destroy now */ 02013 02014 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 02015 if (pkt->method != SIP_OPTIONS) { 02016 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 02017 sip_alreadygone(pkt->owner); 02018 if (option_debug) 02019 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 02020 } 02021 } 02022 } 02023 02024 if (pkt->method == SIP_BYE) { 02025 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 02026 if (pkt->owner->owner) 02027 ast_channel_unlock(pkt->owner->owner); 02028 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 02029 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 02030 } 02031 02032 /* In any case, go ahead and remove the packet */ 02033 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 02034 if (cur == pkt) 02035 break; 02036 } 02037 if (cur) { 02038 if (prev) 02039 prev->next = cur->next; 02040 else 02041 pkt->owner->packets = cur->next; 02042 ast_mutex_unlock(&pkt->owner->lock); 02043 free(cur); 02044 pkt = NULL; 02045 } else 02046 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 02047 if (pkt) 02048 ast_mutex_unlock(&pkt->owner->lock); 02049 return 0; 02050 }
static int scheduler_process_request_queue | ( | const void * | data | ) | [static] |
Definition at line 16030 of file chan_sip.c.
References ast_channel_trylock, ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::lock, and sip_pvt::owner.
Referenced by queue_request().
16031 { 16032 struct sip_pvt *p = (struct sip_pvt *) data; 16033 int recount = 0; 16034 int nounlock = 0; 16035 int lockretry; 16036 16037 for (lockretry = 10; lockretry > 0; lockretry--) { 16038 ast_mutex_lock(&p->lock); 16039 16040 /* lock the owner if it has one -- we may need it */ 16041 /* because this is deadlock-prone, we need to try and unlock if failed */ 16042 if (!p->owner || !ast_channel_trylock(p->owner)) { 16043 break; /* locking succeeded */ 16044 } 16045 16046 if (lockretry != 1) { 16047 ast_mutex_unlock(&p->lock); 16048 /* Sleep for a very short amount of time */ 16049 usleep(1); 16050 } 16051 } 16052 16053 if (!lockretry) { 16054 int retry = !AST_LIST_EMPTY(&p->request_queue); 16055 16056 /* we couldn't get the owner lock, which is needed to process 16057 the queued requests, so return a non-zero value, which will 16058 cause the scheduler to run this request again later if there 16059 still requests to be processed 16060 */ 16061 ast_mutex_unlock(&p->lock); 16062 return retry; 16063 }; 16064 16065 process_request_queue(p, &recount, &nounlock); 16066 p->request_queue_sched_id = -1; 16067 16068 if (p->owner && !nounlock) { 16069 ast_channel_unlock(p->owner); 16070 } 16071 ast_mutex_unlock(&p->lock); 16072 16073 if (recount) { 16074 ast_update_use_count(); 16075 } 16076 16077 return 0; 16078 }
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 2330 of file chan_sip.c.
References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, sip_pvt::flags, get_header(), sip_request::len, sip_request::method, parse_copy(), sip_pvt::recv, sip_pvt::sa, sip_debug_test_pvt(), sip_methods, SIP_NAT_ROUTE, SIP_NO_HISTORY, cfsip_methods::text, and XMIT_CRITICAL.
02331 { 02332 int res; 02333 02334 add_blank(req); 02335 if (sip_debug_test_pvt(p)) { 02336 if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)) 02337 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); 02338 else 02339 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); 02340 } 02341 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02342 struct sip_request tmp; 02343 parse_copy(&tmp, req); 02344 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 02345 } 02346 res = (reliable) ? 02347 __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02348 __sip_xmit(p, req->data, req->len); 02349 return res; 02350 }
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 2302 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.
02303 { 02304 int res; 02305 02306 add_blank(req); 02307 if (sip_debug_test_pvt(p)) { 02308 const struct sockaddr_in *dst = sip_real_dst(p); 02309 02310 ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n", 02311 reliable ? "Reliably " : "", sip_nat_mode(p), 02312 ast_inet_ntoa(dst->sin_addr), 02313 ntohs(dst->sin_port), req->data); 02314 } 02315 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02316 struct sip_request tmp; 02317 parse_copy(&tmp, req); 02318 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 02319 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text); 02320 } 02321 res = (reliable) ? 02322 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02323 __sip_xmit(p, req->data, req->len); 02324 if (res > 0) 02325 return 0; 02326 return res; 02327 }
static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 8282 of file chan_sip.c.
References __set_address_from_contact(), ast_test_flag, sip_pvt::flags, sip_pvt::fullcontact, sip_pvt::recv, sip_pvt::sa, and SIP_NAT_ROUTE.
Referenced by handle_response_invite().
08283 { 08284 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 08285 /* NAT: Don't trust the contact field. Just use what they came to us 08286 with. */ 08287 pvt->sa = pvt->recv; 08288 return 0; 08289 } 08290 08291 return __set_address_from_contact(pvt->fullcontact, &pvt->sa); 08292 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
Set destination from SIP URI.
Definition at line 5945 of file chan_sip.c.
References ahp, ast_copy_string(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_verbose(), debug, hostname, hp, sip_pvt::sa, sip_debug_test_pvt(), and STANDARD_SIP_PORT.
Referenced by reqprep().
05946 { 05947 char *h, *maddr, hostname[256]; 05948 int port, hn; 05949 struct hostent *hp; 05950 struct ast_hostent ahp; 05951 int debug=sip_debug_test_pvt(p); 05952 05953 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 05954 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 05955 05956 if (debug) 05957 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 05958 05959 /* Find and parse hostname */ 05960 h = strchr(uri, '@'); 05961 if (h) 05962 ++h; 05963 else { 05964 h = uri; 05965 if (strncasecmp(h, "sip:", 4) == 0) 05966 h += 4; 05967 else if (strncasecmp(h, "sips:", 5) == 0) 05968 h += 5; 05969 } 05970 hn = strcspn(h, ":;>") + 1; 05971 if (hn > sizeof(hostname)) 05972 hn = sizeof(hostname); 05973 ast_copy_string(hostname, h, hn); 05974 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 05975 h += hn - 1; 05976 05977 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 05978 if (*h == ':') { 05979 /* Parse port */ 05980 ++h; 05981 port = strtol(h, &h, 10); 05982 } 05983 else 05984 port = STANDARD_SIP_PORT; 05985 05986 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 05987 maddr = strstr(h, "maddr="); 05988 if (maddr) { 05989 maddr += 6; 05990 hn = strspn(maddr, "0123456789.") + 1; 05991 if (hn > sizeof(hostname)) 05992 hn = sizeof(hostname); 05993 ast_copy_string(hostname, maddr, hn); 05994 } 05995 05996 hp = ast_gethostbyname(hostname, &ahp); 05997 if (hp == NULL) { 05998 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 05999 return; 06000 } 06001 p->sa.sin_family = AF_INET; 06002 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 06003 p->sa.sin_port = htons(port); 06004 if (debug) 06005 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 06006 }
static void set_insecure_flags | ( | struct ast_flags * | flags, | |
const char * | value, | |||
int | lineno | |||
) | [static] |
Parse the "insecure" setting from sip.conf or from realtime.
flags | a pointer to an ast_flags structure | |
value | the value of the SIP insecure setting | |
lineno | linenumber in sip.conf or -1 for realtime |
Definition at line 16842 of file chan_sip.c.
References ast_copy_string(), ast_false(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_true(), ast_channel::flags, ast_channel::next, SIP_INSECURE_INVITE, and SIP_INSECURE_PORT.
Referenced by handle_common_options().
16843 { 16844 static int dep_insecure_very = 0; 16845 static int dep_insecure_yes = 0; 16846 16847 if (ast_strlen_zero(value)) 16848 return; 16849 16850 if (!strcasecmp(value, "very")) { 16851 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16852 if(!dep_insecure_very) { 16853 if(lineno != -1) 16854 ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno); 16855 else 16856 ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n"); 16857 dep_insecure_very = 1; 16858 } 16859 } 16860 else if (ast_true(value)) { 16861 ast_set_flag(flags, SIP_INSECURE_PORT); 16862 if(!dep_insecure_yes) { 16863 if(lineno != -1) 16864 ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno); 16865 else 16866 ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value); 16867 dep_insecure_yes = 1; 16868 } 16869 } 16870 else if (!ast_false(value)) { 16871 char buf[64]; 16872 char *word, *next; 16873 ast_copy_string(buf, value, sizeof(buf)); 16874 next = buf; 16875 while ((word = strsep(&next, ","))) { 16876 if (!strcasecmp(word, "port")) 16877 ast_set_flag(flags, SIP_INSECURE_PORT); 16878 else if (!strcasecmp(word, "invite")) 16879 ast_set_flag(flags, SIP_INSECURE_INVITE); 16880 else 16881 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 16882 } 16883 } 16884 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 17273 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().
17274 { 17275 if (peer->expire == 0) { 17276 /* Don't reset expire or port time during reload 17277 if we have an active registration 17278 */ 17279 peer->expire = -1; 17280 peer->pokeexpire = -1; 17281 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 17282 } 17283 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 17284 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 17285 strcpy(peer->context, default_context); 17286 strcpy(peer->subscribecontext, default_subscribecontext); 17287 strcpy(peer->language, default_language); 17288 strcpy(peer->mohinterpret, default_mohinterpret); 17289 strcpy(peer->mohsuggest, default_mohsuggest); 17290 peer->addr.sin_family = AF_INET; 17291 peer->defaddr.sin_family = AF_INET; 17292 peer->capability = global_capability; 17293 peer->maxcallbitrate = default_maxcallbitrate; 17294 peer->rtptimeout = global_rtptimeout; 17295 peer->rtpholdtimeout = global_rtpholdtimeout; 17296 peer->rtpkeepalive = global_rtpkeepalive; 17297 peer->allowtransfer = global_allowtransfer; 17298 peer->autoframing = global_autoframing; 17299 strcpy(peer->vmexten, default_vmexten); 17300 peer->secret[0] = '\0'; 17301 peer->md5secret[0] = '\0'; 17302 peer->cid_num[0] = '\0'; 17303 peer->cid_name[0] = '\0'; 17304 peer->fromdomain[0] = '\0'; 17305 peer->fromuser[0] = '\0'; 17306 peer->regexten[0] = '\0'; 17307 peer->mailbox[0] = '\0'; 17308 peer->callgroup = 0; 17309 peer->pickupgroup = 0; 17310 peer->maxms = default_qualify; 17311 peer->prefs = default_prefs; 17312 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 18607 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), ast_strlen_zero(), FALSE, inbuf(), LOG_DEBUG, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), sipdebug, and TRUE.
Referenced by load_module().
18608 { 18609 int no = 0; 18610 int ok = FALSE; 18611 char varbuf[30]; 18612 char *inbuf = (char *) data; 18613 18614 if (ast_strlen_zero(inbuf)) { 18615 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 18616 return 0; 18617 } 18618 ast_channel_lock(chan); 18619 18620 /* Check for headers */ 18621 while (!ok && no <= 50) { 18622 no++; 18623 snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no); 18624 18625 /* Compare without the leading underscores */ 18626 if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL) ) 18627 ok = TRUE; 18628 } 18629 if (ok) { 18630 pbx_builtin_setvar_helper (chan, varbuf, inbuf); 18631 if (sipdebug) 18632 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf); 18633 } else { 18634 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 18635 } 18636 ast_channel_unlock(chan); 18637 return 0; 18638 }
static int sip_addrcmp | ( | char * | name, | |
struct sockaddr_in * | sin | |||
) | [static] |
Support routine for find_peer.
Definition at line 2695 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, inaddrcmp(), and SIP_INSECURE_PORT.
Referenced by find_peer().
02696 { 02697 /* We know name is the first field, so we can cast */ 02698 struct sip_peer *p = (struct sip_peer *) name; 02699 return !(!inaddrcmp(&p->addr, sin) || 02700 (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) && 02701 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 02702 }
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 4548 of file chan_sip.c.
References __ourip, ast_calloc, ast_copy_flags, AST_LIST_HEAD_INIT_NOLOCK, ast_log(), ast_mutex_destroy(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_rtp_codec_setpref(), AST_RTP_DTMF, ast_rtp_new_with_bindaddr(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_settos(), ast_set2_flag, ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_set, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_new_with_bindaddr(), ast_udptl_settos(), ast_variables_destroy(), bindaddr, build_callid_pvt(), build_via(), context, default_prefs, do_setnat(), errno, free, sip_pvt::fromdomain, global_flags, iflist, iflock, INITIAL_CSEQ, io, LOG_DEBUG, make_our_tag(), mohinterpret, mohsuggest, NONE, option_debug, sched, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, SIP_OPTIONS, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_REGISTER, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, text, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.
Referenced by sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
04550 { 04551 struct sip_pvt *p; 04552 04553 if (!(p = ast_calloc(1, sizeof(*p)))) 04554 return NULL; 04555 04556 if (ast_string_field_init(p, 512)) { 04557 free(p); 04558 return NULL; 04559 } 04560 04561 ast_mutex_init(&p->lock); 04562 04563 p->method = intended_method; 04564 p->initid = -1; 04565 p->waitid = -1; 04566 p->autokillid = -1; 04567 p->request_queue_sched_id = -1; 04568 p->subscribed = NONE; 04569 p->stateid = -1; 04570 p->sockfd=-1; 04571 p->prefs = default_prefs; /* Set default codecs for this call */ 04572 04573 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 04574 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 04575 04576 if (sin) { 04577 p->sa = *sin; 04578 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 04579 p->ourip = __ourip; 04580 } else 04581 p->ourip = __ourip; 04582 04583 /* Copy global flags to this PVT at setup. */ 04584 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 04585 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 04586 04587 ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY); 04588 04589 p->branch = ast_random(); 04590 make_our_tag(p->tag, sizeof(p->tag)); 04591 p->ocseq = INITIAL_CSEQ; 04592 04593 if (sip_methods[intended_method].need_rtp) { 04594 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04595 /* If the global videosupport flag is on, we always create a RTP interface for video */ 04596 if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 04597 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04598 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) 04599 p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 04600 if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) { 04601 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", 04602 ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno)); 04603 ast_mutex_destroy(&p->lock); 04604 if (p->chanvars) { 04605 ast_variables_destroy(p->chanvars); 04606 p->chanvars = NULL; 04607 } 04608 free(p); 04609 return NULL; 04610 } 04611 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04612 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04613 ast_rtp_settos(p->rtp, global_tos_audio); 04614 ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); 04615 ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); 04616 ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); 04617 if (p->vrtp) { 04618 ast_rtp_settos(p->vrtp, global_tos_video); 04619 ast_rtp_setdtmf(p->vrtp, 0); 04620 ast_rtp_setdtmfcompensate(p->vrtp, 0); 04621 ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); 04622 ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout); 04623 ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); 04624 } 04625 if (p->udptl) 04626 ast_udptl_settos(p->udptl, global_tos_audio); 04627 p->maxcallbitrate = default_maxcallbitrate; 04628 p->autoframing = global_autoframing; 04629 ast_rtp_codec_setpref(p->rtp, &p->prefs); 04630 } 04631 04632 if (useglobal_nat && sin) { 04633 /* Setup NAT structure according to global settings if we have an address */ 04634 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 04635 p->recv = *sin; 04636 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04637 } 04638 04639 if (p->method != SIP_REGISTER) 04640 ast_string_field_set(p, fromdomain, default_fromdomain); 04641 build_via(p); 04642 if (!callid) 04643 build_callid_pvt(p); 04644 else 04645 ast_string_field_set(p, callid, callid); 04646 /* Assign default music on hold class */ 04647 ast_string_field_set(p, mohinterpret, default_mohinterpret); 04648 ast_string_field_set(p, mohsuggest, default_mohsuggest); 04649 p->capability = global_capability; 04650 p->allowtransfer = global_allowtransfer; 04651 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 04652 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 04653 p->noncodeccapability |= AST_RTP_DTMF; 04654 if (p->udptl) { 04655 p->t38.capability = global_t38_capability; 04656 if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY) 04657 p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 04658 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC) 04659 p->t38.capability |= T38FAX_UDP_EC_FEC; 04660 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE) 04661 p->t38.capability |= T38FAX_UDP_EC_NONE; 04662 p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 04663 p->t38.jointcapability = p->t38.capability; 04664 } 04665 ast_string_field_set(p, context, default_context); 04666 04667 AST_LIST_HEAD_INIT_NOLOCK(&p->request_queue); 04668 04669 /* Add to active dialog list */ 04670 ast_mutex_lock(&iflock); 04671 p->next = iflist; 04672 iflist = p; 04673 ast_mutex_unlock(&iflock); 04674 if (option_debug) 04675 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"); 04676 return p; 04677 }
static void sip_alreadygone | ( | struct sip_pvt * | dialog | ) | [static] |
Definition at line 1676 of file chan_sip.c.
References ast_log(), ast_set_flag, sip_pvt::callid, sip_pvt::flags, LOG_DEBUG, option_debug, and SIP_ALREADYGONE.
Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), retrans_pkt(), sip_indicate(), and sip_sipredirect().
01677 { 01678 if (option_debug > 2) 01679 ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 01680 ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE); 01681 }
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 3736 of file chan_sip.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_setstate(), AST_STATE_UP, sip_pvt::lock, LOG_DEBUG, ast_channel::name, option_debug, SIP_PAGE2_DIALOG_ESTABLISHED, T38_ENABLED, T38_PEER_DIRECT, ast_channel::tech_pvt, transmit_response_with_sdp(), transmit_response_with_t38_sdp(), try_suggested_sip_codec(), and XMIT_CRITICAL.
03737 { 03738 int res = 0; 03739 struct sip_pvt *p = ast->tech_pvt; 03740 03741 ast_mutex_lock(&p->lock); 03742 if (ast->_state != AST_STATE_UP) { 03743 try_suggested_sip_codec(p); 03744 03745 ast_setstate(ast, AST_STATE_UP); 03746 if (option_debug) 03747 ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name); 03748 if (p->t38.state == T38_PEER_DIRECT) { 03749 p->t38.state = T38_ENABLED; 03750 if (option_debug > 1) 03751 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 03752 res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03753 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 03754 } else { 03755 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03756 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 03757 } 03758 } 03759 ast_mutex_unlock(&p->lock); 03760 return res; 03761 }
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 3006 of file chan_sip.c.
References ast_channel::_state, sip_invite_param::addsipheaders, AST_CAUSE_USER_BUSY, AST_FORMAT_AUDIO_MASK, AST_LIST_TRAVERSE, ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_string_field_set, ast_translate_available_formats(), ast_var_name(), ast_var_value(), auto_congest(), sip_pvt::callingpres, t38properties::capability, sip_pvt::capability, ast_channel::cid, cid_name, sip_pvt::cid_name, ast_callerid::cid_pres, sip_invite_param::distinctive_ring, ast_var_t::entries, sip_pvt::flags, ast_channel::hangupcause, INC_CALL_RINGING, sip_pvt::initid, INV_CALLING, sip_pvt::invitestate, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, LOG_DEBUG, sip_pvt::maxtime, ast_channel::name, sip_pvt::noncodeccapability, option_debug, sip_pvt::options, sip_pvt::prefcodec, sip_invite_param::replaces, sched, SIP_INVITE, SIP_OUTGOING, SIP_TRANS_TIMEOUT, SIPBUFSIZE, sipdebug, 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, sip_pvt::username, ast_channel::varshead, sip_invite_param::vxml_url, and XMIT_ERROR.
03007 { 03008 int res, xmitres = 0; 03009 struct sip_pvt *p; 03010 struct varshead *headp; 03011 struct ast_var_t *current; 03012 const char *referer = NULL; /* SIP refererer */ 03013 03014 p = ast->tech_pvt; 03015 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 03016 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 03017 return -1; 03018 } 03019 03020 /* Check whether there is vxml_url, distinctive ring variables */ 03021 headp=&ast->varshead; 03022 AST_LIST_TRAVERSE(headp,current,entries) { 03023 /* Check whether there is a VXML_URL variable */ 03024 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 03025 p->options->vxml_url = ast_var_value(current); 03026 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 03027 p->options->uri_options = ast_var_value(current); 03028 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 03029 /* Check whether there is a ALERT_INFO variable */ 03030 p->options->distinctive_ring = ast_var_value(current); 03031 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 03032 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 03033 p->options->addsipheaders = 1; 03034 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 03035 /* This is a transfered call */ 03036 p->options->transfer = 1; 03037 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 03038 /* This is the referer */ 03039 referer = ast_var_value(current); 03040 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 03041 /* We're replacing a call. */ 03042 p->options->replaces = ast_var_value(current); 03043 } else if (!strcasecmp(ast_var_name(current), "T38CALL")) { 03044 p->t38.state = T38_LOCAL_DIRECT; 03045 if (option_debug) 03046 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 03047 } 03048 03049 } 03050 03051 res = 0; 03052 ast_set_flag(&p->flags[0], SIP_OUTGOING); 03053 03054 if (p->options->transfer) { 03055 char buf[SIPBUFSIZE/2]; 03056 03057 if (referer) { 03058 if (sipdebug && option_debug > 2) 03059 ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer); 03060 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 03061 } else 03062 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 03063 ast_string_field_set(p, cid_name, buf); 03064 } 03065 if (option_debug) 03066 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 03067 03068 res = update_call_counter(p, INC_CALL_RINGING); 03069 if ( res != -1 ) { 03070 p->callingpres = ast->cid.cid_pres; 03071 p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec); 03072 p->jointnoncodeccapability = p->noncodeccapability; 03073 03074 /* If there are no audio formats left to offer, punt */ 03075 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 03076 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 03077 res = -1; 03078 } else { 03079 p->t38.jointcapability = p->t38.capability; 03080 if (option_debug > 1) 03081 ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability); 03082 xmitres = transmit_invite(p, SIP_INVITE, 1, 2); 03083 if (xmitres == XMIT_ERROR) 03084 return -1; /* Transmission error */ 03085 03086 p->invitestate = INV_CALLING; 03087 03088 /* Initialize auto-congest time */ 03089 AST_SCHED_DEL(sched, p->initid); 03090 p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p); 03091 } 03092 } else { 03093 ast->hangupcause = AST_CAUSE_USER_BUSY; 03094 } 03095 return res; 03096 }
static int sip_cancel_destroy | ( | struct sip_pvt * | p | ) | [static] |
Cancel destruction of SIP dialog.
Definition at line 2172 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().
02173 { 02174 int res = 0; 02175 if (p->autokillid > -1) { 02176 if (!(res = ast_sched_del(sched, p->autokillid))) { 02177 append_history(p, "CancelDestroy", ""); 02178 p->autokillid = -1; 02179 } 02180 } 02181 return res; 02182 }
static int sip_debug_test_addr | ( | const struct sockaddr_in * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 1758 of file chan_sip.c.
References sipdebug.
Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().
01759 { 01760 if (!sipdebug) 01761 return 0; 01762 if (debugaddr.sin_addr.s_addr) { 01763 if (((ntohs(debugaddr.sin_port) != 0) 01764 && (debugaddr.sin_port != addr->sin_port)) 01765 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01766 return 0; 01767 } 01768 return 1; 01769 }
static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 1784 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().
01785 { 01786 if (!sipdebug) 01787 return 0; 01788 return sip_debug_test_addr(sip_real_dst(p)); 01789 }
static void sip_destroy | ( | struct sip_pvt * | p | ) | [static] |
Destroy SIP call structure.
Definition at line 3378 of file chan_sip.c.
References __sip_destroy(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), sip_pvt::callid, iflock, LOG_DEBUG, and option_debug.
Referenced by __sip_autodestruct(), handle_request_subscribe(), reload_config(), sip_destroy_peer(), sip_notify(), sip_poke_noanswer(), sip_poke_peer(), sip_registry_destroy(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
03379 { 03380 ast_mutex_lock(&iflock); 03381 if (option_debug > 2) 03382 ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid); 03383 __sip_destroy(p, 1); 03384 ast_mutex_unlock(&iflock); 03385 }
static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 2505 of file chan_sip.c.
References ast_free_ha(), ast_log(), ast_test_flag, ast_variables_destroy(), sip_peer::auth, sip_peer::call, sip_peer::chanvars, clear_realm_authentication(), FALSE, sip_peer::flags, free, sip_peer::ha, LOG_DEBUG, sip_peer::mwipvt, sip_peer::name, option_debug, register_peer_exten(), sip_destroy(), SIP_PAGE2_SELFDESTRUCT, and SIP_REALTIME.
Referenced by __sip_autodestruct(), __sip_destroy(), _sip_show_peer(), build_peer(), check_user_full(), create_addr(), expire_register(), function_sippeer(), handle_request_subscribe(), handle_response_peerpoke(), parse_register_contact(), reg_source_db(), register_verify(), sip_devicestate(), sip_do_debug_peer(), sip_do_reload(), sip_poke_all_peers(), sip_poke_noanswer(), sip_poke_peer(), sip_poke_peer_s(), sip_prune_realtime(), unload_module(), and update_call_counter().
02506 { 02507 if (option_debug > 2) 02508 ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name); 02509 02510 /* Delete it, it needs to disappear */ 02511 if (peer->call) 02512 sip_destroy(peer->call); 02513 02514 if (peer->mwipvt) /* We have an active subscription, delete it */ 02515 sip_destroy(peer->mwipvt); 02516 02517 if (peer->chanvars) { 02518 ast_variables_destroy(peer->chanvars); 02519 peer->chanvars = NULL; 02520 } 02521 02522 register_peer_exten(peer, FALSE); 02523 ast_free_ha(peer->ha); 02524 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT)) 02525 apeerobjs--; 02526 else if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) 02527 rpeerobjs--; 02528 else 02529 speerobjs--; 02530 clear_realm_authentication(peer->auth); 02531 peer->auth = NULL; 02532 free(peer); 02533 }
static void sip_destroy_user | ( | struct sip_user * | user | ) | [static] |
Remove user object from in-memory storage.
Definition at line 2723 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, sip_user::name, option_debug, and SIP_REALTIME.
Referenced by check_user_full(), sip_show_user(), unload_module(), and update_call_counter().
02724 { 02725 if (option_debug > 2) 02726 ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name); 02727 ast_free_ha(user->ha); 02728 if (user->chanvars) { 02729 ast_variables_destroy(user->chanvars); 02730 user->chanvars = NULL; 02731 } 02732 if (ast_test_flag(&user->flags[0], SIP_REALTIME)) 02733 ruserobjs--; 02734 else 02735 suserobjs--; 02736 free(user); 02737 }
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 16677 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().
16678 { 16679 char *host; 16680 char *tmp; 16681 16682 struct hostent *hp; 16683 struct ast_hostent ahp; 16684 struct sip_peer *p; 16685 16686 int res = AST_DEVICE_INVALID; 16687 16688 /* make sure data is not null. Maybe unnecessary, but better be safe */ 16689 host = ast_strdupa(data ? data : ""); 16690 if ((tmp = strchr(host, '@'))) 16691 host = tmp + 1; 16692 16693 if (option_debug > 2) 16694 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 16695 16696 /* If find_peer asks for a realtime peer, then this breaks rtautoclear. This 16697 * is because when a peer tries to autoexpire, the last thing it does is to 16698 * queue up an event telling the system that the devicestate has changed 16699 * (presumably to unavailable). If we ask for a realtime peer here, this would 16700 * load it BACK into memory, thus defeating the point of trying to trying to 16701 * clear dead hosts out of memory. 16702 */ 16703 if ((p = find_peer(host, NULL, 0, 1))) { 16704 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 16705 /* we have an address for the peer */ 16706 16707 /* Check status in this order 16708 - Hold 16709 - Ringing 16710 - Busy (enforced only by call limit) 16711 - Inuse (we have a call) 16712 - Unreachable (qualify) 16713 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 16714 for registered devices */ 16715 16716 if (p->onHold) 16717 /* First check for hold or ring states */ 16718 res = AST_DEVICE_ONHOLD; 16719 else if (p->inRinging) { 16720 if (p->inRinging == p->inUse) 16721 res = AST_DEVICE_RINGING; 16722 else 16723 res = AST_DEVICE_RINGINUSE; 16724 } else if (p->call_limit && (p->inUse == p->call_limit)) 16725 /* check call limit */ 16726 res = AST_DEVICE_BUSY; 16727 else if (p->call_limit && p->inUse) 16728 /* Not busy, but we do have a call */ 16729 res = AST_DEVICE_INUSE; 16730 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 16731 /* We don't have a call. Are we reachable at all? Requires qualify= */ 16732 res = AST_DEVICE_UNAVAILABLE; 16733 else /* Default reply if we're registered and have no other data */ 16734 res = AST_DEVICE_NOT_INUSE; 16735 } else { 16736 /* there is no address, it's unavailable */ 16737 res = AST_DEVICE_UNAVAILABLE; 16738 } 16739 ASTOBJ_UNREF(p,sip_destroy_peer); 16740 } else { 16741 char *port = strchr(host, ':'); 16742 if (port) 16743 *port = '\0'; 16744 hp = ast_gethostbyname(host, &ahp); 16745 if (hp) 16746 res = AST_DEVICE_UNKNOWN; 16747 } 16748 16749 return res; 16750 }
static int sip_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 11567 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.
11568 { 11569 int oldsipdebug = sipdebug_console; 11570 if (argc != 3) { 11571 if (argc != 5) 11572 return RESULT_SHOWUSAGE; 11573 else if (strcmp(argv[3], "ip") == 0) 11574 return sip_do_debug_ip(fd, argc, argv); 11575 else if (strcmp(argv[3], "peer") == 0) 11576 return sip_do_debug_peer(fd, argc, argv); 11577 else 11578 return RESULT_SHOWUSAGE; 11579 } 11580 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11581 memset(&debugaddr, 0, sizeof(debugaddr)); 11582 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11583 return RESULT_SUCCESS; 11584 }
static int sip_do_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11586 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.
11587 { 11588 int oldsipdebug = sipdebug_console; 11589 char *newargv[6] = { "sip", "set", "debug", NULL }; 11590 if (argc != 2) { 11591 if (argc != 4) 11592 return RESULT_SHOWUSAGE; 11593 else if (strcmp(argv[2], "ip") == 0) { 11594 newargv[3] = argv[2]; 11595 newargv[4] = argv[3]; 11596 return sip_do_debug_ip(fd, argc + 1, newargv); 11597 } else if (strcmp(argv[2], "peer") == 0) { 11598 newargv[3] = argv[2]; 11599 newargv[4] = argv[3]; 11600 return sip_do_debug_peer(fd, argc + 1, newargv); 11601 } else 11602 return RESULT_SHOWUSAGE; 11603 } 11604 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11605 memset(&debugaddr, 0, sizeof(debugaddr)); 11606 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11607 return RESULT_SUCCESS; 11608 }
static int sip_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP Debugging in CLI.
Definition at line 11513 of file chan_sip.c.
References ahp, ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), ast_set_flag, debugaddr, global_flags, hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
11514 { 11515 struct hostent *hp; 11516 struct ast_hostent ahp; 11517 int port = 0; 11518 char *p, *arg; 11519 11520 /* sip set debug ip <ip> */ 11521 if (argc != 5) 11522 return RESULT_SHOWUSAGE; 11523 p = arg = argv[4]; 11524 strsep(&p, ":"); 11525 if (p) 11526 port = atoi(p); 11527 hp = ast_gethostbyname(arg, &ahp); 11528 if (hp == NULL) 11529 return RESULT_SHOWUSAGE; 11530 11531 debugaddr.sin_family = AF_INET; 11532 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 11533 debugaddr.sin_port = htons(port); 11534 if (port == 0) 11535 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 11536 else 11537 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 11538 11539 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11540 11541 return RESULT_SUCCESS; 11542 }
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 11545 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().
11546 { 11547 struct sip_peer *peer; 11548 if (argc != 5) 11549 return RESULT_SHOWUSAGE; 11550 peer = find_peer(argv[4], NULL, 1, 0); 11551 if (peer) { 11552 if (peer->addr.sin_addr.s_addr) { 11553 debugaddr.sin_family = AF_INET; 11554 debugaddr.sin_addr = peer->addr.sin_addr; 11555 debugaddr.sin_port = peer->addr.sin_port; 11556 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 11557 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11558 } else 11559 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]); 11560 ASTOBJ_UNREF(peer,sip_destroy_peer); 11561 } else 11562 ast_cli(fd, "No such peer '%s'\n", argv[4]); 11563 return RESULT_SUCCESS; 11564 }
static int sip_do_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP History logging (CLI).
Definition at line 11686 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and TRUE.
11687 { 11688 if (argc != 2) { 11689 return RESULT_SHOWUSAGE; 11690 } 11691 recordhistory = TRUE; 11692 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 11693 return RESULT_SUCCESS; 11694 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 18753 of file chan_sip.c.
References ast_log(), ASTOBJ_CONTAINER_PRUNE_MARKED, LOG_DEBUG, peerl, reload_config(), sip_destroy_peer(), sip_poke_all_peers(), and sip_send_all_registers().
Referenced by do_monitor().
18754 { 18755 reload_config(reason); 18756 18757 /* Prune peers who still are supposed to be deleted */ 18758 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 18759 if (option_debug > 3) 18760 ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n"); 18761 18762 /* Send qualify (OPTIONS) to all peers */ 18763 sip_poke_all_peers(); 18764 18765 /* Register with all services */ 18766 sip_send_all_registers(); 18767 18768 if (option_debug > 3) 18769 ast_log(LOG_DEBUG, "--------------- SIP reload done\n"); 18770 18771 return 0; 18772 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 18552 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_dsp_free(), ast_dsp_new(), ast_dsp_set_features(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_DTMF, ast_rtp_setdtmf(), ast_set_flag, ast_test_flag, DSP_FEATURE_DTMF_DETECT, sip_pvt::flags, sip_pvt::jointnoncodeccapability, sip_pvt::lock, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, and sip_pvt::vad.
Referenced by load_module().
18553 { 18554 struct sip_pvt *p; 18555 char *mode; 18556 if (data) 18557 mode = (char *)data; 18558 else { 18559 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 18560 return 0; 18561 } 18562 ast_channel_lock(chan); 18563 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 18564 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 18565 ast_channel_unlock(chan); 18566 return 0; 18567 } 18568 p = chan->tech_pvt; 18569 if (!p) { 18570 ast_channel_unlock(chan); 18571 return 0; 18572 } 18573 ast_mutex_lock(&p->lock); 18574 if (!strcasecmp(mode,"info")) { 18575 ast_clear_flag(&p->flags[0], SIP_DTMF); 18576 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 18577 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 18578 } else if (!strcasecmp(mode,"rfc2833")) { 18579 ast_clear_flag(&p->flags[0], SIP_DTMF); 18580 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 18581 p->jointnoncodeccapability |= AST_RTP_DTMF; 18582 } else if (!strcasecmp(mode,"inband")) { 18583 ast_clear_flag(&p->flags[0], SIP_DTMF); 18584 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 18585 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 18586 } else 18587 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 18588 if (p->rtp) 18589 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 18590 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 18591 if (!p->vad) { 18592 p->vad = ast_dsp_new(); 18593 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 18594 } 18595 } else { 18596 if (p->vad) { 18597 ast_dsp_free(p->vad); 18598 p->vad = NULL; 18599 } 18600 } 18601 ast_mutex_unlock(&p->lock); 18602 ast_channel_unlock(chan); 18603 return 0; 18604 }
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 11371 of file chan_sip.c.
References AST_LIST_TRAVERSE, ast_log(), sip_pvt::callid, sip_history::event, sip_pvt::history, sip_history::list, LOG_DEBUG, LOG_NOTICE, option_debug, sipdebug, and sip_pvt::subscribed.
Referenced by __sip_destroy().
11372 { 11373 int x = 0; 11374 struct sip_history *hist; 11375 static int errmsg = 0; 11376 11377 if (!dialog) 11378 return; 11379 11380 if (!option_debug && !sipdebug) { 11381 if (!errmsg) { 11382 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 11383 errmsg = 1; 11384 } 11385 return; 11386 } 11387 11388 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 11389 if (dialog->subscribed) 11390 ast_log(LOG_DEBUG, " * Subscription\n"); 11391 else 11392 ast_log(LOG_DEBUG, " * SIP Call\n"); 11393 if (dialog->history) 11394 AST_LIST_TRAVERSE(dialog->history, hist, list) 11395 ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); 11396 if (!x) 11397 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 11398 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 11399 }
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 3844 of file chan_sip.c.
References append_history, AST_FLAG_ZOMBIE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::callid, sip_pvt::lock, LOG_DEBUG, ast_channel::name, option_debug, sip_pvt::owner, sip_set_rtp_peer(), and ast_channel::tech_pvt.
03845 { 03846 int ret = -1; 03847 struct sip_pvt *p; 03848 03849 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug) 03850 ast_log(LOG_DEBUG, "New channel is zombie\n"); 03851 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug) 03852 ast_log(LOG_DEBUG, "Old channel is zombie\n"); 03853 03854 if (!newchan || !newchan->tech_pvt) { 03855 if (!newchan) 03856 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 03857 else 03858 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 03859 return -1; 03860 } 03861 p = newchan->tech_pvt; 03862 03863 if (!p) { 03864 ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n"); 03865 return -1; 03866 } 03867 03868 ast_mutex_lock(&p->lock); 03869 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 03870 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 03871 if (p->owner != oldchan) 03872 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 03873 else { 03874 p->owner = newchan; 03875 /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native 03876 RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be 03877 able to do this if the masquerade happens before the bridge breaks (e.g., AMI 03878 redirect of both channels). Note that a channel can not be masqueraded *into* 03879 a native bridge. So there is no danger that this breaks a native bridge that 03880 should stay up. */ 03881 sip_set_rtp_peer(newchan, NULL, NULL, 0, 0); 03882 ret = 0; 03883 } 03884 if (option_debug > 2) 03885 ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 03886 03887 ast_mutex_unlock(&p->lock); 03888 return ret; 03889 }
static int sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Return SIP UA's codec (part of the RTP interface).
Definition at line 18697 of file chan_sip.c.
References sip_pvt::capability, sip_pvt::jointcapability, and ast_channel::tech_pvt.
18698 { 18699 struct sip_pvt *p = chan->tech_pvt; 18700 return p->jointcapability ? p->jointcapability : p->capability; 18701 }
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 18405 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.
18406 { 18407 struct sip_pvt *p = NULL; 18408 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 18409 18410 if (!(p = chan->tech_pvt)) 18411 return AST_RTP_GET_FAILED; 18412 18413 ast_mutex_lock(&p->lock); 18414 if (!(p->rtp)) { 18415 ast_mutex_unlock(&p->lock); 18416 return AST_RTP_GET_FAILED; 18417 } 18418 18419 *rtp = p->rtp; 18420 18421 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 18422 res = AST_RTP_TRY_PARTIAL; 18423 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 18424 res = AST_RTP_TRY_NATIVE; 18425 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 18426 res = AST_RTP_GET_FAILED; 18427 18428 ast_mutex_unlock(&p->lock); 18429 18430 return res; 18431 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 18270 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.
18271 { 18272 struct sip_pvt *p; 18273 struct ast_udptl *udptl = NULL; 18274 18275 p = chan->tech_pvt; 18276 if (!p) 18277 return NULL; 18278 18279 ast_mutex_lock(&p->lock); 18280 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 18281 udptl = p->udptl; 18282 ast_mutex_unlock(&p->lock); 18283 return udptl; 18284 }
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 18434 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.
18435 { 18436 struct sip_pvt *p = NULL; 18437 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 18438 18439 if (!(p = chan->tech_pvt)) 18440 return AST_RTP_GET_FAILED; 18441 18442 ast_mutex_lock(&p->lock); 18443 if (!(p->vrtp)) { 18444 ast_mutex_unlock(&p->lock); 18445 return AST_RTP_GET_FAILED; 18446 } 18447 18448 *rtp = p->vrtp; 18449 18450 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 18451 res = AST_RTP_TRY_NATIVE; 18452 18453 ast_mutex_unlock(&p->lock); 18454 18455 return res; 18456 }
static int sip_handle_t38_reinvite | ( | struct ast_channel * | chan, | |
struct sip_pvt * | pvt, | |||
int | reinvite | |||
) | [static] |
Handle T38 reinvite.
Definition at line 18322 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_get_local_max_datagram(), ast_udptl_get_peer(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_local_max_datagram(), sip_pvt::callid, sip_pvt::flags, sip_pvt::initreq, t38properties::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, ast_channel::name, sip_pvt::ourip, sip_pvt::owner, t38properties::peercapability, sip_pvt::pendinginvite, SIP_CAN_REINVITE, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, t38properties::state, sip_pvt::t38, T38_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().
18323 { 18324 struct sip_pvt *p; 18325 int flag = 0; 18326 18327 p = chan->tech_pvt; 18328 if (!p || !pvt->udptl) 18329 return -1; 18330 18331 /* Setup everything on the other side like offered/responded from first side */ 18332 ast_mutex_lock(&p->lock); 18333 18334 /*! \todo check if this is not set earlier when setting up the PVT. If not 18335 maybe it should move there. */ 18336 p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability; 18337 18338 ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 18339 ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 18340 ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl)); 18341 18342 if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */ 18343 /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects, 18344 not really T38 re-invites which are different. In this 18345 case it's used properly, to see if we can reinvite over 18346 NAT 18347 */ 18348 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 18349 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 18350 flag =1; 18351 } else { 18352 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18353 } 18354 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 18355 if (!p->pendinginvite) { 18356 if (option_debug > 2) { 18357 if (flag) 18358 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)); 18359 else 18360 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)); 18361 } 18362 transmit_reinvite_with_t38_sdp(p); 18363 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18364 if (option_debug > 2) { 18365 if (flag) 18366 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)); 18367 else 18368 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)); 18369 } 18370 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18371 } 18372 } 18373 /* Reset lastrtprx timer */ 18374 p->lastrtprx = p->lastrtptx = time(NULL); 18375 ast_mutex_unlock(&p->lock); 18376 return 0; 18377 } else { /* If we are handling sending 200 OK to the other side of the bridge */ 18378 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 18379 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 18380 flag = 1; 18381 } else { 18382 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18383 } 18384 if (option_debug > 2) { 18385 if (flag) 18386 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)); 18387 else 18388 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)); 18389 } 18390 pvt->t38.state = T38_ENABLED; 18391 p->t38.state = T38_ENABLED; 18392 if (option_debug > 1) { 18393 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 18394 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 18395 } 18396 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 18397 p->lastrtprx = p->lastrtptx = time(NULL); 18398 ast_mutex_unlock(&p->lock); 18399 return 0; 18400 } 18401 }
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 3551 of file chan_sip.c.
References __sip_pretend_ack(), ast_channel::_state, append_history, ast_cause2str(), ast_clear_flag, ast_dsp_free(), AST_FLAG_ZOMBIE, ast_log(), ast_module_unref(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_quality(), AST_SCHED_DEL, ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, sip_pvt::autokillid, sip_pvt::callid, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, INC_CALL_LIMIT, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, sched, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_DEFER_BYE_ON_TRANSFER, SIP_INC_COUNT, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_PAGE2_CALL_ONHOLD, SIP_PENDINGBYE, sip_scheddestroy(), sipdebug, stop_media_flows(), ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, update_call_counter(), sip_pvt::username, sip_pvt::vad, and XMIT_RELIABLE.
03552 { 03553 struct sip_pvt *p = ast->tech_pvt; 03554 int needcancel = FALSE; 03555 int needdestroy = 0; 03556 struct ast_channel *oldowner = ast; 03557 03558 if (!p) { 03559 if (option_debug) 03560 ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n"); 03561 return 0; 03562 } 03563 03564 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 03565 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03566 if (option_debug && sipdebug) 03567 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03568 update_call_counter(p, DEC_CALL_LIMIT); 03569 } 03570 if (option_debug >3) 03571 ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 03572 if (p->autokillid > -1 && sip_cancel_destroy(p)) 03573 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03574 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03575 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 03576 ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY); 03577 p->owner->tech_pvt = NULL; 03578 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 03579 return 0; 03580 } 03581 if (option_debug) { 03582 if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug) 03583 ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 03584 else { 03585 if (option_debug) 03586 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 03587 } 03588 } 03589 if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 03590 ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n"); 03591 03592 ast_mutex_lock(&p->lock); 03593 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03594 if (option_debug && sipdebug) 03595 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03596 update_call_counter(p, DEC_CALL_LIMIT); 03597 } 03598 03599 /* Determine how to disconnect */ 03600 if (p->owner != ast) { 03601 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 03602 ast_mutex_unlock(&p->lock); 03603 return 0; 03604 } 03605 /* If the call is not UP, we need to send CANCEL instead of BYE */ 03606 if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) { 03607 needcancel = TRUE; 03608 if (option_debug > 3) 03609 ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 03610 } 03611 03612 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 03613 03614 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->owner->hangupcause) : "Unknown"); 03615 03616 /* Disconnect */ 03617 if (p->vad) 03618 ast_dsp_free(p->vad); 03619 03620 p->owner = NULL; 03621 ast->tech_pvt = NULL; 03622 03623 ast_module_unref(ast_module_info->self); 03624 03625 /* Do not destroy this pvt until we have timeout or 03626 get an answer to the BYE or INVITE/CANCEL 03627 If we get no answer during retransmit period, drop the call anyway. 03628 (Sorry, mother-in-law, you can't deny a hangup by sending 03629 603 declined to BYE...) 03630 */ 03631 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) 03632 needdestroy = 1; /* Set destroy flag at end of this function */ 03633 else if (p->invitestate != INV_CALLING) 03634 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03635 03636 /* Start the process if it's not already started */ 03637 if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 03638 if (needcancel) { /* Outgoing call, not up */ 03639 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03640 /* stop retransmitting an INVITE that has not received a response */ 03641 __sip_pretend_ack(p); 03642 p->invitestate = INV_CANCELLED; 03643 03644 /* if we can't send right now, mark it pending */ 03645 if (p->invitestate == INV_CALLING) { 03646 /* We can't send anything in CALLING state */ 03647 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03648 /* Do we need a timer here if we don't hear from them at all? Yes we do or else we will get hung dialogs and those are no fun. */ 03649 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03650 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 03651 } else { 03652 /* Send a new request: CANCEL */ 03653 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 03654 /* Actually don't destroy us yet, wait for the 487 on our original 03655 INVITE, but do set an autodestruct just in case we never get it. */ 03656 needdestroy = 0; 03657 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03658 } 03659 if ( p->initid != -1 ) { 03660 /* channel still up - reverse dec of inUse counter 03661 only if the channel is not auto-congested */ 03662 update_call_counter(p, INC_CALL_LIMIT); 03663 } 03664 } else { /* Incoming call, not up */ 03665 const char *res; 03666 if (ast->hangupcause && (res = hangup_cause2sip(ast->hangupcause))) 03667 transmit_response_reliable(p, res, &p->initreq); 03668 else 03669 transmit_response_reliable(p, "603 Declined", &p->initreq); 03670 p->invitestate = INV_TERMINATED; 03671 } 03672 } else { /* Call is in UP state, send BYE */ 03673 if (!p->pendinginvite) { 03674 char *audioqos = ""; 03675 char *videoqos = ""; 03676 if (p->rtp) 03677 audioqos = ast_rtp_get_quality(p->rtp, NULL); 03678 if (p->vrtp) 03679 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 03680 /* Send a hangup */ 03681 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03682 03683 /* Get RTCP quality before end of call */ 03684 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 03685 if (p->rtp) 03686 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 03687 if (p->vrtp) 03688 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 03689 } 03690 if (p->rtp && oldowner) 03691 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); 03692 if (p->vrtp && oldowner) 03693 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos); 03694 } else { 03695 /* Note we will need a BYE when this all settles out 03696 but we can't send one while we have "INVITE" outstanding. */ 03697 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03698 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 03699 AST_SCHED_DEL(sched, p->waitid); 03700 if (sip_cancel_destroy(p)) 03701 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03702 } 03703 } 03704 } 03705 if (needdestroy) 03706 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 03707 ast_mutex_unlock(&p->lock); 03708 return 0; 03709 }
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 3960 of file chan_sip.c.
References ast_channel::_state, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_new_source(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, sip_pvt::flags, sip_pvt::initreq, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, sip_pvt::lock, sip_pvt::mohinterpret, sip_pvt::rtp, sip_alreadygone(), SIP_NOVIDEO, SIP_OUTGOING, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_YES, SIP_PROGRESS_SENT, SIP_RINGING, ast_channel::tech_pvt, transmit_info_with_vidupdate(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), sip_pvt::vrtp, and XMIT_UNRELIABLE.
03961 { 03962 struct sip_pvt *p = ast->tech_pvt; 03963 int res = 0; 03964 03965 ast_mutex_lock(&p->lock); 03966 switch(condition) { 03967 case AST_CONTROL_RINGING: 03968 if (ast->_state == AST_STATE_RING) { 03969 p->invitestate = INV_EARLY_MEDIA; 03970 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 03971 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 03972 /* Send 180 ringing if out-of-band seems reasonable */ 03973 transmit_response(p, "180 Ringing", &p->initreq); 03974 ast_set_flag(&p->flags[0], SIP_RINGING); 03975 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 03976 break; 03977 } else { 03978 /* Well, if it's not reasonable, just send in-band */ 03979 } 03980 } 03981 res = -1; 03982 break; 03983 case AST_CONTROL_BUSY: 03984 if (ast->_state != AST_STATE_UP) { 03985 transmit_response_reliable(p, "486 Busy Here", &p->initreq); 03986 p->invitestate = INV_COMPLETED; 03987 sip_alreadygone(p); 03988 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03989 break; 03990 } 03991 res = -1; 03992 break; 03993 case AST_CONTROL_CONGESTION: 03994 if (ast->_state != AST_STATE_UP) { 03995 transmit_response_reliable(p, "503 Service Unavailable", &p->initreq); 03996 p->invitestate = INV_COMPLETED; 03997 sip_alreadygone(p); 03998 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03999 break; 04000 } 04001 res = -1; 04002 break; 04003 case AST_CONTROL_PROCEEDING: 04004 if ((ast->_state != AST_STATE_UP) && 04005 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 04006 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 04007 transmit_response(p, "100 Trying", &p->initreq); 04008 p->invitestate = INV_PROCEEDING; 04009 break; 04010 } 04011 res = -1; 04012 break; 04013 case AST_CONTROL_PROGRESS: 04014 if ((ast->_state != AST_STATE_UP) && 04015 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 04016 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 04017 p->invitestate = INV_EARLY_MEDIA; 04018 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 04019 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 04020 break; 04021 } 04022 res = -1; 04023 break; 04024 case AST_CONTROL_HOLD: 04025 ast_rtp_new_source(p->rtp); 04026 ast_moh_start(ast, data, p->mohinterpret); 04027 break; 04028 case AST_CONTROL_UNHOLD: 04029 ast_rtp_new_source(p->rtp); 04030 ast_moh_stop(ast); 04031 break; 04032 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 04033 if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 04034 transmit_info_with_vidupdate(p); 04035 /* ast_rtcp_send_h261fur(p->vrtp); */ 04036 } else 04037 res = -1; 04038 break; 04039 case AST_CONTROL_SRCUPDATE: 04040 ast_rtp_new_source(p->rtp); 04041 break; 04042 case -1: 04043 res = -1; 04044 break; 04045 default: 04046 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 04047 res = -1; 04048 break; 04049 } 04050 ast_mutex_unlock(&p->lock); 04051 return res; 04052 }
static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 1778 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().
01779 { 01780 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT"; 01781 }
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 4060 of file chan_sip.c.
References accountcode, sip_pvt::accountcode, ast_channel::adsicpe, ast_channel::amaflags, sip_pvt::amaflags, append_history, AST_ADSI_UNAVAILABLE, ast_best_codec(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc(), ast_codec_choose(), ast_copy_string(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_features(), AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_fd(), ast_uri_decode(), ast_verbose(), sip_pvt::callgroup, ast_channel::callgroup, sip_pvt::callid, sip_pvt::callingpres, sip_pvt::capability, sip_pvt::chanvars, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, sip_pvt::cid_name, sip_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_channel::context, sip_pvt::context, sip_pvt::domain, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DTMF_DETECT, ast_channel::exten, sip_pvt::exten, f, ast_channel::fds, sip_pvt::flags, sip_pvt::from, sip_pvt::fromdomain, sip_pvt::fromname, sip_pvt::fromuser, sip_pvt::fullcontact, global_jbconf, sip_pvt::jointcapability, language, sip_pvt::language, sip_pvt::lock, LOG_DEBUG, ast_variable::name, ast_channel::nativeformats, ast_variable::next, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::peername, sip_pvt::pickupgroup, ast_channel::pickupgroup, sip_pvt::prefcodec, sip_pvt::prefs, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, sip_pvt::rdnis, ast_channel::readformat, ast_channel::rings, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_NO_HISTORY, sip_tech, sip_tech_info, SIPBUFSIZE, t38properties::state, sip_pvt::t38, T38_PEER_DIRECT, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::udptl, sip_pvt::uri, sip_pvt::useragent, sip_pvt::username, sip_pvt::vad, ast_variable::value, VERBOSE_PREFIX_3, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by handle_request_invite(), and sip_request_call().
04061 { 04062 struct ast_channel *tmp; 04063 struct ast_variable *v = NULL; 04064 int fmt; 04065 int what; 04066 int needvideo = 0, video = 0; 04067 char *decoded_exten; 04068 04069 if (option_debug != 0) { 04070 ast_verbose(VERBOSE_PREFIX_3 "NEW SIP CHANNEL, title: <%s>\n", title?title:"Null"); 04071 ast_verbose(VERBOSE_PREFIX_3 "from: %s\n", i->from); 04072 ast_verbose(VERBOSE_PREFIX_3 "username: <%s>\n", i->username); 04073 ast_verbose(VERBOSE_PREFIX_3 "peername: <%s>\n", i->peername); 04074 ast_verbose(VERBOSE_PREFIX_3 "fromdomain: %s\n", i->fromdomain); 04075 ast_verbose(VERBOSE_PREFIX_3 "fromuser: %s\n", i->fromuser); 04076 ast_verbose(VERBOSE_PREFIX_3 "fromname: %s\n", i->fromname); 04077 ast_verbose(VERBOSE_PREFIX_3 "fullcontact: %s\n", i->fullcontact); 04078 } 04079 04080 { 04081 char my_name[128]; /* pick a good name */ 04082 const char *f, *fromdomain = NULL; 04083 04084 if (!ast_strlen_zero(i->fromdomain) && strchr(i->fromdomain,':')) 04085 fromdomain = strchr(i->fromdomain,':') + 1; /* skip ':' */ 04086 else 04087 fromdomain = i->fromdomain; 04088 04089 if (!ast_strlen_zero(i->username)) { 04090 if (!ast_strlen_zero(title) && strcmp(i->username, title)) { 04091 /* title not empty and different from username */ 04092 snprintf(my_name, sizeof(my_name), "%s@%s", i->username, title); 04093 } else { 04094 /* username not empty, title is empty or equal to username */ 04095 snprintf(my_name, sizeof(my_name), "%s", i->username); 04096 } 04097 } else { /* username empty */ 04098 if (!ast_strlen_zero(i->peername)) { 04099 /* call from unregisted peer */ 04100 snprintf(my_name, sizeof(my_name), "%s", i->peername); 04101 } else { /* username and peername empty */ 04102 if (!ast_strlen_zero(title)) { /* title not empty */ 04103 snprintf(my_name, sizeof(my_name), "%s", title); 04104 } else if (!ast_strlen_zero(i->from)) { /* title empty, From: not empty */ 04105 f = i->from; 04106 if (!strncmp(f, "sip:", 4)) 04107 f += 4; 04108 snprintf(my_name, sizeof(my_name), "%s", f); 04109 } else { /* fallback to fromdomain */ 04110 snprintf(my_name, sizeof(my_name), "%s", fromdomain); 04111 } 04112 } 04113 } 04114 ast_mutex_unlock(&i->lock); 04115 /* Don't hold a sip pvt lock while we allocate a channel */ 04116 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); 04117 04118 } 04119 if (!tmp) { 04120 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 04121 ast_mutex_lock(&i->lock); 04122 return NULL; 04123 } 04124 ast_mutex_lock(&i->lock); 04125 04126 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO) 04127 tmp->tech = &sip_tech_info; 04128 else 04129 tmp->tech = &sip_tech; 04130 04131 /* Select our native format based on codec preference until we receive 04132 something from another device to the contrary. */ 04133 if (i->jointcapability) { /* The joint capabilities of us and peer */ 04134 what = i->jointcapability; 04135 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 04136 } else if (i->capability) { /* Our configured capability for this peer */ 04137 what = i->capability; 04138 video = i->capability & AST_FORMAT_VIDEO_MASK; 04139 } else { 04140 what = global_capability; /* Global codec support */ 04141 video = global_capability & AST_FORMAT_VIDEO_MASK; 04142 } 04143 04144 /* Set the native formats for audio and merge in video */ 04145 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video; 04146 if (option_debug > 2) { 04147 char buf[SIPBUFSIZE]; 04148 ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats)); 04149 ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability)); 04150 ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability)); 04151 ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1))); 04152 if (i->prefcodec) 04153 ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec)); 04154 } 04155 04156 /* XXX Why are we choosing a codec from the native formats?? */ 04157 fmt = ast_best_codec(tmp->nativeformats); 04158 04159 /* If we have a prefcodec setting, we have an inbound channel that set a 04160 preferred format for this call. Otherwise, we check the jointcapability 04161 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 04162 */ 04163 if (i->vrtp) { 04164 if (i->prefcodec) 04165 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 04166 else 04167 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 04168 } 04169 04170 if (option_debug > 2) { 04171 if (needvideo) 04172 ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n"); 04173 else 04174 ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n"); 04175 } 04176 04177 04178 04179 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 04180 i->vad = ast_dsp_new(); 04181 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 04182 if (global_relaxdtmf) 04183 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 04184 } 04185 if (i->rtp) { 04186 tmp->fds[0] = ast_rtp_fd(i->rtp); 04187 tmp->fds[1] = ast_rtcp_fd(i->rtp); 04188 } 04189 if (needvideo && i->vrtp) { 04190 tmp->fds[2] = ast_rtp_fd(i->vrtp); 04191 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 04192 } 04193 if (i->udptl) { 04194 tmp->fds[5] = ast_udptl_fd(i->udptl); 04195 } 04196 if (state == AST_STATE_RING) 04197 tmp->rings = 1; 04198 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 04199 tmp->writeformat = fmt; 04200 tmp->rawwriteformat = fmt; 04201 tmp->readformat = fmt; 04202 tmp->rawreadformat = fmt; 04203 tmp->tech_pvt = i; 04204 04205 tmp->callgroup = i->callgroup; 04206 tmp->pickupgroup = i->pickupgroup; 04207 tmp->cid.cid_pres = i->callingpres; 04208 if (!ast_strlen_zero(i->accountcode)) 04209 ast_string_field_set(tmp, accountcode, i->accountcode); 04210 if (i->amaflags) 04211 tmp->amaflags = i->amaflags; 04212 if (!ast_strlen_zero(i->language)) 04213 ast_string_field_set(tmp, language, i->language); 04214 i->owner = tmp; 04215 ast_module_ref(ast_module_info->self); 04216 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 04217 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 04218 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 04219 * structure so that there aren't issues when forming URI's 04220 */ 04221 decoded_exten = ast_strdupa(i->exten); 04222 ast_uri_decode(decoded_exten); 04223 ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten)); 04224 04225 /* Don't use ast_set_callerid() here because it will 04226 * generate an unnecessary NewCallerID event */ 04227 tmp->cid.cid_ani = ast_strdup(i->cid_num); 04228 if (!ast_strlen_zero(i->rdnis)) 04229 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 04230 04231 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 04232 tmp->cid.cid_dnid = ast_strdup(i->exten); 04233 04234 tmp->priority = 1; 04235 if (!ast_strlen_zero(i->uri)) 04236 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 04237 if (!ast_strlen_zero(i->domain)) 04238 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 04239 if (!ast_strlen_zero(i->useragent)) 04240 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 04241 if (!ast_strlen_zero(i->callid)) 04242 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 04243 if (i->rtp) 04244 ast_jb_configure(tmp, &global_jbconf); 04245 04246 /* If the INVITE contains T.38 SDP information set the proper channel variable so a created outgoing call will also have T.38 */ 04247 if (i->udptl && i->t38.state == T38_PEER_DIRECT) 04248 pbx_builtin_setvar_helper(tmp, "_T38CALL", "1"); 04249 04250 /* Set channel variables for this call from configuration */ 04251 for (v = i->chanvars ; v ; v = v->next) 04252 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04253 04254 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 04255 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04256 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 04257 ast_hangup(tmp); 04258 tmp = NULL; 04259 } 04260 04261 if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY)) 04262 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 04263 04264 return tmp; 04265 }
static int sip_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP Debugging in CLI.
Definition at line 11667 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11668 { 11669 if (argc != 4) 11670 return RESULT_SHOWUSAGE; 11671 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11672 ast_cli(fd, "SIP Debugging Disabled\n"); 11673 return RESULT_SUCCESS; 11674 }
static int sip_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11676 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11677 { 11678 if (argc != 3) 11679 return RESULT_SHOWUSAGE; 11680 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11681 ast_cli(fd, "SIP Debugging Disabled\n"); 11682 return RESULT_SUCCESS; 11683 }
static int sip_no_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP History logging (CLI).
Definition at line 11697 of file chan_sip.c.
References ast_cli(), FALSE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
11698 { 11699 if (argc != 3) { 11700 return RESULT_SHOWUSAGE; 11701 } 11702 recordhistory = FALSE; 11703 ast_cli(fd, "SIP History Recording Disabled\n"); 11704 return RESULT_SUCCESS; 11705 }
static int sip_notify | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Cli command to send SIP notify to peer.
Definition at line 11611 of file chan_sip.c.
References __ourip, add_header(), ast_cli(), ast_log(), ast_sip_ouraddrfor(), ast_unescape_semicolon(), ast_variable_browse(), build_callid_pvt(), build_via(), create_addr(), DEFAULT_TRANS_TIMEOUT, initreqprep(), notify_types, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), and var.
11612 { 11613 struct ast_variable *varlist; 11614 int i; 11615 11616 if (argc < 4) 11617 return RESULT_SHOWUSAGE; 11618 11619 if (!notify_types) { 11620 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 11621 return RESULT_FAILURE; 11622 } 11623 11624 varlist = ast_variable_browse(notify_types, argv[2]); 11625 11626 if (!varlist) { 11627 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 11628 return RESULT_FAILURE; 11629 } 11630 11631 for (i = 3; i < argc; i++) { 11632 struct sip_pvt *p; 11633 struct sip_request req; 11634 struct ast_variable *var; 11635 11636 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { 11637 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 11638 return RESULT_FAILURE; 11639 } 11640 11641 if (create_addr(p, argv[i])) { 11642 /* Maybe they're not registered, etc. */ 11643 sip_destroy(p); 11644 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 11645 continue; 11646 } 11647 11648 initreqprep(&req, p, SIP_NOTIFY); 11649 11650 for (var = varlist; var; var = var->next) 11651 add_header(&req, var->name, ast_unescape_semicolon(var->value)); 11652 11653 /* Recalculate our side, and recalculate Call ID */ 11654 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 11655 p->ourip = __ourip; 11656 build_via(p); 11657 build_callid_pvt(p); 11658 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 11659 transmit_sip_request(p, &req); 11660 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11661 } 11662 11663 return RESULT_SUCCESS; 11664 }
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 13447 of file chan_sip.c.
References ast_channel::accountcode, ast_channel::amaflags, ast_calloc, AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc(), ast_channel_lock, ast_channel_masquerade(), ast_channel_trylock, ast_channel_unlock, ast_copy_string(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_pthread_create_background, AST_STATE_DOWN, ast_channel::context, copy_request(), DEADLOCK_AVOIDANCE, ast_channel::exten, free, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, ast_channel::name, option_debug, ast_channel::priority, ast_channel::readformat, sip_park_thread(), ast_channel::tech_pvt, and ast_channel::writeformat.
Referenced by handle_request_refer().
13448 { 13449 struct sip_dual *d; 13450 struct ast_channel *transferee, *transferer; 13451 /* Chan2m: The transferer, chan1m: The transferee */ 13452 pthread_t th; 13453 13454 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 13455 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); 13456 if ((!transferer) || (!transferee)) { 13457 if (transferee) { 13458 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13459 ast_hangup(transferee); 13460 } 13461 if (transferer) { 13462 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13463 ast_hangup(transferer); 13464 } 13465 return -1; 13466 } 13467 13468 /* Make formats okay */ 13469 transferee->readformat = chan1->readformat; 13470 transferee->writeformat = chan1->writeformat; 13471 13472 /* Prepare for taking over the channel */ 13473 ast_channel_masquerade(transferee, chan1); 13474 13475 /* Setup the extensions and such */ 13476 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 13477 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 13478 transferee->priority = chan1->priority; 13479 13480 /* We make a clone of the peer channel too, so we can play 13481 back the announcement */ 13482 13483 /* Make formats okay */ 13484 transferer->readformat = chan2->readformat; 13485 transferer->writeformat = chan2->writeformat; 13486 13487 /* Prepare for taking over the channel. Go ahead and grab this channel 13488 * lock here to avoid a deadlock with callbacks into the channel driver 13489 * that hold the channel lock and want the pvt lock. */ 13490 while (ast_channel_trylock(chan2)) { 13491 struct sip_pvt *pvt = chan2->tech_pvt; 13492 DEADLOCK_AVOIDANCE(&pvt->lock); 13493 } 13494 ast_channel_masquerade(transferer, chan2); 13495 ast_channel_unlock(chan2); 13496 13497 /* Setup the extensions and such */ 13498 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 13499 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 13500 transferer->priority = chan2->priority; 13501 13502 ast_channel_lock(transferer); 13503 if (ast_do_masquerade(transferer)) { 13504 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 13505 ast_channel_unlock(transferer); 13506 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13507 ast_hangup(transferer); 13508 return -1; 13509 } 13510 ast_channel_unlock(transferer); 13511 if (!transferer || !transferee) { 13512 if (!transferer) { 13513 if (option_debug) 13514 ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n"); 13515 } 13516 if (!transferee) { 13517 if (option_debug) 13518 ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n"); 13519 } 13520 return -1; 13521 } 13522 if ((d = ast_calloc(1, sizeof(*d)))) { 13523 pthread_attr_t attr; 13524 13525 pthread_attr_init(&attr); 13526 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 13527 13528 /* Save original request for followup */ 13529 copy_request(&d->req, req); 13530 d->chan1 = transferee; /* Transferee */ 13531 d->chan2 = transferer; /* Transferer */ 13532 d->seqno = seqno; 13533 if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) { 13534 /* Could not start thread */ 13535 free(d); /* We don't need it anymore. If thread is created, d will be free'd 13536 by sip_park_thread() */ 13537 pthread_attr_destroy(&attr); 13538 return 0; 13539 } 13540 pthread_attr_destroy(&attr); 13541 } 13542 return -1; 13543 }
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 13380 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, ast_channel::name, option_debug, sip_dual::req, sip_dual::seqno, ast_channel::tech_pvt, transmit_message_with_text(), transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by sip_park().
13381 { 13382 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 13383 struct sip_dual *d; 13384 struct sip_request req; 13385 int ext; 13386 int res; 13387 13388 d = stuff; 13389 transferee = d->chan1; 13390 transferer = d->chan2; 13391 copy_request(&req, &d->req); 13392 13393 if (!transferee || !transferer) { 13394 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 13395 return NULL; 13396 } 13397 if (option_debug > 3) 13398 ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 13399 13400 ast_channel_lock(transferee); 13401 if (ast_do_masquerade(transferee)) { 13402 ast_log(LOG_WARNING, "Masquerade failed.\n"); 13403 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 13404 ast_channel_unlock(transferee); 13405 return NULL; 13406 } 13407 ast_channel_unlock(transferee); 13408 13409 res = ast_park_call(transferee, transferer, 0, &ext); 13410 13411 13412 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 13413 if (!res) { 13414 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 13415 } else { 13416 /* Then tell the transferer what happened */ 13417 sprintf(buf, "Call parked on extension '%d'", ext); 13418 transmit_message_with_text(transferer->tech_pvt, buf); 13419 } 13420 #endif 13421 13422 /* Any way back to the current call??? */ 13423 /* Transmit response to the REFER request */ 13424 transmit_response(transferer->tech_pvt, "202 Accepted", &req); 13425 if (!res) { 13426 /* Transfer succeeded */ 13427 append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext); 13428 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 13429 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 13430 ast_hangup(transferer); /* This will cause a BYE */ 13431 if (option_debug) 13432 ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext); 13433 } else { 13434 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 13435 append_history(transferer->tech_pvt, "SIPpark","Parking failed\n"); 13436 if (option_debug) 13437 ast_log(LOG_DEBUG, "SIP Call parked failed \n"); 13438 /* Do not hangup call */ 13439 } 13440 free(d); 13441 return NULL; 13442 }
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 8782 of file chan_sip.c.
References ast_device_state_changed(), find_peer(), sip_peer::name, sip_peer::onHold, and sip_pvt::peername.
Referenced by change_hold_state(), and update_call_counter().
08783 { 08784 struct sip_peer *peer = find_peer(p->peername, NULL, 1, 0); 08785 08786 if (!peer) 08787 return; 08788 08789 /* If they put someone on hold, increment the value... otherwise decrement it */ 08790 if (hold) 08791 peer->onHold++; 08792 else 08793 peer->onHold--; 08794 08795 /* Request device state update */ 08796 ast_device_state_changed("SIP/%s", peer->name); 08797 08798 return; 08799 }
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 18707 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, peerl, sched, sip_destroy_peer(), and sip_poke_peer_s().
Referenced by load_module(), and sip_do_reload().
18708 { 18709 int ms = 0; 18710 18711 if (!speerobjs) /* No peers, just give up */ 18712 return; 18713 18714 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 18715 ASTOBJ_WRLOCK(iterator); 18716 if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) { 18717 struct sip_peer *peer_ptr = iterator; 18718 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 18719 } 18720 ms += 100; 18721 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, ASTOBJ_REF(iterator)); 18722 if (iterator->pokeexpire == -1) { 18723 struct sip_peer *peer_ptr = iterator; 18724 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 18725 } 18726 ASTOBJ_UNLOCK(iterator); 18727 } while (0) 18728 ); 18729 }
static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 16533 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ASTOBJ_UNREF, sip_peer::call, DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::name, sip_peer::pokeexpire, sched, sip_destroy(), sip_destroy_peer(), and sip_poke_peer_s().
Referenced by sip_poke_peer().
16534 { 16535 struct sip_peer *peer = (struct sip_peer *)data; 16536 16537 peer->pokeexpire = -1; 16538 if (peer->lastms > -1) { 16539 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 16540 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 16541 } 16542 if (peer->call) 16543 sip_destroy(peer->call); 16544 peer->call = NULL; 16545 peer->lastms = -1; 16546 ast_device_state_changed("SIP/%s", peer->name); 16547 16548 /* This function gets called one place outside of the scheduler ... */ 16549 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16550 struct sip_peer *peer_ptr = peer; 16551 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16552 } 16553 16554 /* There is no need to ASTOBJ_REF() here. Just let the scheduled callback 16555 * inherit the reference that the current callback already has. */ 16556 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 16557 if (peer->pokeexpire == -1) { 16558 ASTOBJ_UNREF(peer, sip_destroy_peer); 16559 } 16560 16561 return 0; 16562 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 16567 of file chan_sip.c.
References __ourip, sip_peer::addr, ast_copy_flags, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_set, ast_strlen_zero(), ASTOBJ_REF, ASTOBJ_UNREF, build_callid_pvt(), build_via(), sip_peer::call, sip_peer::flags, sip_pvt::flags, sip_peer::fullcontact, sip_peer::lastms, LOG_NOTICE, sip_peer::maxms, sip_pvt::ourip, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::recv, sip_pvt::relatedpeer, sip_pvt::sa, sched, sip_alloc(), sip_destroy(), sip_destroy_peer(), SIP_FLAGS_TO_COPY, SIP_INVITE, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_TCP, SIP_PAGE2_TCP_CONNECTED, sip_poke_noanswer(), sipdebug, sip_peer::sockfd, sip_pvt::sockfd, sip_peer::tohost, transmit_invite(), sip_pvt::username, and XMIT_ERROR.
Referenced by parse_register_contact(), reg_source_db(), and sip_poke_peer_s().
16568 { 16569 struct sip_pvt *p; 16570 int xmitres = 0; 16571 16572 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 16573 /* IF we have no IP, or this isn't to be monitored, return 16574 imeediately after clearing things out */ 16575 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16576 struct sip_peer *peer_ptr = peer; 16577 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16578 } 16579 peer->lastms = 0; 16580 peer->call = NULL; 16581 return 0; 16582 } 16583 if (peer->call) { 16584 if (sipdebug) 16585 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 16586 sip_destroy(peer->call); 16587 } 16588 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS))) 16589 return -1; 16590 16591 p->sa = peer->addr; 16592 p->recv = peer->addr; 16593 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 16594 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16595 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_TCP | SIP_PAGE2_TCP_CONNECTED); 16596 p->sockfd = peer->sockfd; 16597 16598 /* Send OPTIONs to peer's fullcontact */ 16599 if (!ast_strlen_zero(peer->fullcontact)) 16600 ast_string_field_set(p, fullcontact, peer->fullcontact); 16601 16602 if (!ast_strlen_zero(peer->tohost)) 16603 ast_string_field_set(p, tohost, peer->tohost); 16604 else 16605 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 16606 16607 /* Recalculate our side, and recalculate Call ID */ 16608 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16609 p->ourip = __ourip; 16610 build_via(p); 16611 build_callid_pvt(p); 16612 16613 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16614 struct sip_peer *peer_ptr = peer; 16615 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16616 } 16617 16618 p->relatedpeer = ASTOBJ_REF(peer); 16619 ast_set_flag(&p->flags[0], SIP_OUTGOING); 16620 #ifdef VOCAL_DATA_HACK 16621 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 16622 xmitres = transmit_invite(p, SIP_INVITE, 0, 2); 16623 #else 16624 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); 16625 #endif 16626 gettimeofday(&peer->ps, NULL); 16627 if (xmitres == XMIT_ERROR) { 16628 sip_poke_noanswer(ASTOBJ_REF(peer)); /* Immediately unreachable, network problems */ 16629 } else { 16630 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16631 struct sip_peer *peer_ptr = peer; 16632 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16633 } 16634 peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, ASTOBJ_REF(peer)); 16635 if (peer->pokeexpire == -1) { 16636 struct sip_peer *peer_ptr = peer; 16637 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16638 } 16639 } 16640 16641 return 0; 16642 }
static int sip_poke_peer_s | ( | const void * | data | ) | [static] |
Poke peer (send qualify to check if peer is alive and well).
Definition at line 8121 of file chan_sip.c.
References ASTOBJ_UNREF, sip_peer::pokeexpire, sip_destroy_peer(), and sip_poke_peer().
Referenced by handle_response_peerpoke(), reg_source_db(), sip_poke_all_peers(), and sip_poke_noanswer().
08122 { 08123 struct sip_peer *peer = (struct sip_peer *) data; 08124 08125 peer->pokeexpire = -1; 08126 08127 sip_poke_peer(peer); 08128 08129 ASTOBJ_UNREF(peer, sip_destroy_peer); 08130 08131 return 0; 08132 }
static int sip_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 10390 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.
10391 { 10392 struct sip_peer *peer; 10393 struct sip_user *user; 10394 int pruneuser = FALSE; 10395 int prunepeer = FALSE; 10396 int multi = FALSE; 10397 char *name = NULL; 10398 regex_t regexbuf; 10399 10400 switch (argc) { 10401 case 4: 10402 if (!strcasecmp(argv[3], "user")) 10403 return RESULT_SHOWUSAGE; 10404 if (!strcasecmp(argv[3], "peer")) 10405 return RESULT_SHOWUSAGE; 10406 if (!strcasecmp(argv[3], "like")) 10407 return RESULT_SHOWUSAGE; 10408 if (!strcasecmp(argv[3], "all")) { 10409 multi = TRUE; 10410 pruneuser = prunepeer = TRUE; 10411 } else { 10412 pruneuser = prunepeer = TRUE; 10413 name = argv[3]; 10414 } 10415 break; 10416 case 5: 10417 if (!strcasecmp(argv[4], "like")) 10418 return RESULT_SHOWUSAGE; 10419 if (!strcasecmp(argv[3], "all")) 10420 return RESULT_SHOWUSAGE; 10421 if (!strcasecmp(argv[3], "like")) { 10422 multi = TRUE; 10423 name = argv[4]; 10424 pruneuser = prunepeer = TRUE; 10425 } else if (!strcasecmp(argv[3], "user")) { 10426 pruneuser = TRUE; 10427 if (!strcasecmp(argv[4], "all")) 10428 multi = TRUE; 10429 else 10430 name = argv[4]; 10431 } else if (!strcasecmp(argv[3], "peer")) { 10432 prunepeer = TRUE; 10433 if (!strcasecmp(argv[4], "all")) 10434 multi = TRUE; 10435 else 10436 name = argv[4]; 10437 } else 10438 return RESULT_SHOWUSAGE; 10439 break; 10440 case 6: 10441 if (strcasecmp(argv[4], "like")) 10442 return RESULT_SHOWUSAGE; 10443 if (!strcasecmp(argv[3], "user")) { 10444 pruneuser = TRUE; 10445 name = argv[5]; 10446 } else if (!strcasecmp(argv[3], "peer")) { 10447 prunepeer = TRUE; 10448 name = argv[5]; 10449 } else 10450 return RESULT_SHOWUSAGE; 10451 break; 10452 default: 10453 return RESULT_SHOWUSAGE; 10454 } 10455 10456 if (multi && name) { 10457 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 10458 return RESULT_SHOWUSAGE; 10459 } 10460 10461 if (multi) { 10462 if (prunepeer) { 10463 int pruned = 0; 10464 10465 ASTOBJ_CONTAINER_WRLOCK(&peerl); 10466 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10467 ASTOBJ_RDLOCK(iterator); 10468 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10469 ASTOBJ_UNLOCK(iterator); 10470 continue; 10471 }; 10472 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10473 ASTOBJ_MARK(iterator); 10474 pruned++; 10475 } 10476 ASTOBJ_UNLOCK(iterator); 10477 } while (0) ); 10478 if (pruned) { 10479 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 10480 ast_cli(fd, "%d peers pruned.\n", pruned); 10481 } else 10482 ast_cli(fd, "No peers found to prune.\n"); 10483 ASTOBJ_CONTAINER_UNLOCK(&peerl); 10484 } 10485 if (pruneuser) { 10486 int pruned = 0; 10487 10488 ASTOBJ_CONTAINER_WRLOCK(&userl); 10489 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10490 ASTOBJ_RDLOCK(iterator); 10491 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10492 ASTOBJ_UNLOCK(iterator); 10493 continue; 10494 }; 10495 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10496 ASTOBJ_MARK(iterator); 10497 pruned++; 10498 } 10499 ASTOBJ_UNLOCK(iterator); 10500 } while (0) ); 10501 if (pruned) { 10502 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 10503 ast_cli(fd, "%d users pruned.\n", pruned); 10504 } else 10505 ast_cli(fd, "No users found to prune.\n"); 10506 ASTOBJ_CONTAINER_UNLOCK(&userl); 10507 } 10508 } else { 10509 if (prunepeer) { 10510 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 10511 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10512 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 10513 ASTOBJ_CONTAINER_LINK(&peerl, peer); 10514 } else 10515 ast_cli(fd, "Peer '%s' pruned.\n", name); 10516 ASTOBJ_UNREF(peer, sip_destroy_peer); 10517 } else 10518 ast_cli(fd, "Peer '%s' not found.\n", name); 10519 } 10520 if (pruneuser) { 10521 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 10522 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10523 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 10524 ASTOBJ_CONTAINER_LINK(&userl, user); 10525 } else 10526 ast_cli(fd, "User '%s' pruned.\n", name); 10527 ASTOBJ_UNREF(user, sip_destroy_user); 10528 } else 10529 ast_cli(fd, "User '%s' not found.\n", name); 10530 } 10531 } 10532 10533 return RESULT_SUCCESS; 10534 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static] |
Read SIP RTP from channel.
Definition at line 4468 of file chan_sip.c.
References ast_channel::_state, ast_bridged_channel(), AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, ast_set_flag, AST_STATE_UP, ast_test_flag, FALSE, sip_pvt::flags, ast_frame::frametype, INV_EARLY_MEDIA, sip_pvt::invitestate, sip_pvt::lastrtprx, sip_pvt::lock, LOG_DEBUG, ast_channel::name, option_debug, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PENDINGBYE, sip_rtp_read(), t38properties::state, sip_pvt::t38, T38_DISABLED, T38_LOCAL_REINVITE, t38properties::t38support, ast_channel::tech_pvt, and transmit_reinvite_with_t38_sdp().
04469 { 04470 struct ast_frame *fr; 04471 struct sip_pvt *p = ast->tech_pvt; 04472 int faxdetected = FALSE; 04473 04474 ast_mutex_lock(&p->lock); 04475 fr = sip_rtp_read(ast, p, &faxdetected); 04476 p->lastrtprx = time(NULL); 04477 04478 /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */ 04479 /* 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 */ 04480 if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) { 04481 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 04482 if (!p->pendinginvite) { 04483 if (option_debug > 2) 04484 ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name); 04485 p->t38.state = T38_LOCAL_REINVITE; 04486 transmit_reinvite_with_t38_sdp(p); 04487 if (option_debug > 1) 04488 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name); 04489 } 04490 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04491 if (option_debug > 2) 04492 ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name); 04493 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04494 } 04495 } 04496 04497 /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */ 04498 if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) { 04499 fr = &ast_null_frame; 04500 } 04501 04502 ast_mutex_unlock(&p->lock); 04503 return fr; 04504 }
static struct sockaddr_in * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static] |
The real destination address for a write.
Definition at line 1772 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().
01773 { 01774 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa; 01775 }
static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 7922 of file chan_sip.c.
References ast_calloc, and sip_pvt::refer.
Referenced by get_also_info(), handle_request_invite(), handle_request_refer(), and transmit_refer().
07923 { 07924 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 07925 return p->refer ? 1 : 0; 07926 }
static int sip_reg_timeout | ( | const void * | data | ) | [static] |
Registration timeout, register again.
Definition at line 7665 of file chan_sip.c.
References __sip_pretend_ack(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, EVENT_FLAG_SYSTEM, sip_pvt::flags, sip_registry::hostname, sip_pvt::lock, LOG_NOTICE, manager_event(), REG_STATE_FAILED, REG_STATE_UNREGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), SIP_NEEDDESTROY, SIP_REGISTER, sip_registry_destroy(), sip_registry::timeout, transmit_register(), and sip_registry::username.
Referenced by transmit_register().
07666 { 07667 07668 /* if we are here, our registration timed out, so we'll just do it over */ 07669 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 07670 struct sip_pvt *p; 07671 int res; 07672 07673 /* if we couldn't get a reference to the registry object, punt */ 07674 if (!r) 07675 return 0; 07676 07677 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 07678 if (r->call) { 07679 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 07680 in the single SIP manager thread. */ 07681 p = r->call; 07682 ast_mutex_lock(&p->lock); 07683 if (p->registry) 07684 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 07685 r->call = NULL; 07686 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 07687 /* Pretend to ACK anything just in case */ 07688 __sip_pretend_ack(p); 07689 ast_mutex_unlock(&p->lock); 07690 } 07691 /* If we have a limit, stop registration and give up */ 07692 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 07693 /* Ok, enough is enough. Don't try any more */ 07694 /* We could add an external notification here... 07695 steal it from app_voicemail :-) */ 07696 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 07697 r->regstate = REG_STATE_FAILED; 07698 } else { 07699 r->regstate = REG_STATE_UNREGISTERED; 07700 r->timeout = -1; 07701 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 07702 } 07703 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)); 07704 ASTOBJ_UNREF(r, sip_registry_destroy); 07705 return 0; 07706 }
static int sip_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 4800 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ast_log(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, sip_registry::authuser, sip_registry::contact, FALSE, free, hostname, INITIAL_CSEQ, LOG_ERROR, regl, secret, sip_registry_destroy(), and username.
04801 { 04802 struct sip_registry *reg; 04803 int portnum = 0; 04804 char username[256] = ""; 04805 char *hostname=NULL, *secret=NULL, *authuser=NULL; 04806 char *porta=NULL; 04807 char *contact=NULL; 04808 04809 if (!value) 04810 return -1; 04811 ast_copy_string(username, value, sizeof(username)); 04812 /* First split around the last '@' then parse the two components. */ 04813 hostname = strrchr(username, '@'); /* allow @ in the first part */ 04814 if (hostname) 04815 *hostname++ = '\0'; 04816 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 04817 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 04818 return -1; 04819 } 04820 /* split user[:secret[:authuser]] */ 04821 secret = strchr(username, ':'); 04822 if (secret) { 04823 *secret++ = '\0'; 04824 authuser = strchr(secret, ':'); 04825 if (authuser) 04826 *authuser++ = '\0'; 04827 } 04828 /* split host[:port][/contact] */ 04829 contact = strchr(hostname, '/'); 04830 if (contact) 04831 *contact++ = '\0'; 04832 if (ast_strlen_zero(contact)) 04833 contact = "s"; 04834 porta = strchr(hostname, ':'); 04835 if (porta) { 04836 *porta++ = '\0'; 04837 portnum = atoi(porta); 04838 if (portnum == 0) { 04839 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 04840 return -1; 04841 } 04842 } 04843 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 04844 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 04845 return -1; 04846 } 04847 04848 if (ast_string_field_init(reg, 256)) { 04849 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 04850 free(reg); 04851 return -1; 04852 } 04853 04854 regobjs++; 04855 ASTOBJ_INIT(reg); 04856 ast_string_field_set(reg, contact, contact); 04857 if (!ast_strlen_zero(username)) 04858 ast_string_field_set(reg, username, username); 04859 if (hostname) 04860 ast_string_field_set(reg, hostname, hostname); 04861 if (authuser) 04862 ast_string_field_set(reg, authuser, authuser); 04863 if (secret) 04864 ast_string_field_set(reg, secret, secret); 04865 reg->expire = -1; 04866 reg->timeout = -1; 04867 reg->refresh = default_expiry; 04868 reg->portno = portnum; 04869 reg->callid_valid = FALSE; 04870 reg->ocseq = INITIAL_CSEQ; 04871 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 04872 ASTOBJ_UNREF(reg,sip_registry_destroy); 04873 return 0; 04874 }
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 3100 of file chan_sip.c.
References ast_log(), AST_SCHED_DEL, ast_string_field_free_memory, sip_registry::call, sip_registry::expire, free, sip_registry::hostname, LOG_DEBUG, option_debug, sip_pvt::registry, sched, sip_destroy(), sip_registry::timeout, and sip_registry::username.
Referenced by __sip_destroy(), handle_response_register(), sip_reg_timeout(), sip_register(), sip_reregister(), and unload_module().
03101 { 03102 /* Really delete */ 03103 if (option_debug > 2) 03104 ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 03105 03106 if (reg->call) { 03107 /* Clear registry before destroying to ensure 03108 we don't get reentered trying to grab the registry lock */ 03109 reg->call->registry = NULL; 03110 if (option_debug > 2) 03111 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 03112 sip_destroy(reg->call); 03113 } 03114 AST_SCHED_DEL(sched, reg->expire); 03115 AST_SCHED_DEL(sched, reg->timeout); 03116 ast_string_field_free_memory(reg); 03117 regobjs--; 03118 free(reg); 03119 03120 }
static int sip_reinvite_retry | ( | const void * | data | ) | [static] |
Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler.
Definition at line 12340 of file chan_sip.c.
References ast_set_flag, sip_pvt::flags, SIP_NEEDREINVITE, and sip_pvt::waitid.
Referenced by handle_response_invite().
12341 { 12342 struct sip_pvt *p = (struct sip_pvt *) data; 12343 12344 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 12345 p->waitid = -1; 12346 return 0; 12347 }
static int sip_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Force reload of module from cli.
Definition at line 18775 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), CHANNEL_CLI_RELOAD, CHANNEL_MODULE_RELOAD, restart_monitor(), sip_reload_lock, and TRUE.
Referenced by reload().
18776 { 18777 ast_mutex_lock(&sip_reload_lock); 18778 if (sip_reloading) 18779 ast_verbose("Previous SIP reload not yet done\n"); 18780 else { 18781 sip_reloading = TRUE; 18782 if (fd) 18783 sip_reloadreason = CHANNEL_CLI_RELOAD; 18784 else 18785 sip_reloadreason = CHANNEL_MODULE_RELOAD; 18786 } 18787 ast_mutex_unlock(&sip_reload_lock); 18788 restart_monitor(); 18789 18790 return 0; 18791 }
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 16754 of file chan_sip.c.
References __ourip, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_string(), AST_FORMAT_MAX_AUDIO, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), build_callid_pvt(), build_via(), create_addr(), ext, sip_pvt::flags, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, option_debug, sip_pvt::options, sip_pvt::peername, restart_monitor(), sip_alloc(), sip_destroy(), SIP_INVITE, sip_new(), SIP_PAGE2_OUTGOING_CALL, and username.
16755 { 16756 int oldformat; 16757 struct sip_pvt *p; 16758 struct ast_channel *tmpc = NULL; 16759 char *ext, *host; 16760 char tmp[256]; 16761 char *dest = data; 16762 16763 oldformat = format; 16764 if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { 16765 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)); 16766 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 16767 return NULL; 16768 } 16769 if (option_debug) 16770 ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 16771 16772 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { 16773 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data); 16774 *cause = AST_CAUSE_SWITCH_CONGESTION; 16775 return NULL; 16776 } 16777 16778 ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL); 16779 16780 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 16781 sip_destroy(p); 16782 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 16783 *cause = AST_CAUSE_SWITCH_CONGESTION; 16784 return NULL; 16785 } 16786 16787 ast_copy_string(tmp, dest, sizeof(tmp)); 16788 host = strchr(tmp, '@'); 16789 if (host) { 16790 *host++ = '\0'; 16791 ext = tmp; 16792 } else { 16793 ext = strchr(tmp, '/'); 16794 if (ext) 16795 *ext++ = '\0'; 16796 host = tmp; 16797 } 16798 16799 if (create_addr(p, host)) { 16800 *cause = AST_CAUSE_UNREGISTERED; 16801 if (option_debug > 2) 16802 ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n"); 16803 sip_destroy(p); 16804 return NULL; 16805 } 16806 if (ast_strlen_zero(p->peername) && ext) 16807 ast_string_field_set(p, peername, ext); 16808 /* Recalculate our side, and recalculate Call ID */ 16809 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16810 p->ourip = __ourip; 16811 build_via(p); 16812 build_callid_pvt(p); 16813 16814 /* We have an extension to call, don't use the full contact here */ 16815 /* This to enable dialing registered peers with extension dialling, 16816 like SIP/peername/extension 16817 SIP/peername will still use the full contact */ 16818 if (ext) { 16819 ast_string_field_set(p, username, ext); 16820 ast_string_field_free(p, fullcontact); 16821 } 16822 #if 0 16823 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 16824 #endif 16825 p->prefcodec = oldformat; /* Format for this call */ 16826 ast_mutex_lock(&p->lock); 16827 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 16828 ast_mutex_unlock(&p->lock); 16829 if (!tmpc) 16830 sip_destroy(p); 16831 ast_update_use_count(); 16832 restart_monitor(); 16833 return tmpc; 16834 }
static int sip_reregister | ( | const void * | data | ) | [static] |
Update registration with SIP Proxy.
Definition at line 7633 of file chan_sip.c.
References __sip_do_register(), append_history, ast_log(), ast_test_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, sip_registry::expire, sip_pvt::flags, sip_registry::hostname, LOG_NOTICE, SIP_NO_HISTORY, sip_registry_destroy(), sipdebug, and sip_registry::username.
Referenced by handle_response_register(), and sip_send_all_registers().
07634 { 07635 /* if we are here, we know that we need to reregister. */ 07636 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 07637 07638 /* if we couldn't get a reference to the registry object, punt */ 07639 if (!r) 07640 return 0; 07641 07642 if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 07643 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 07644 /* Since registry's are only added/removed by the the monitor thread, this 07645 may be overkill to reference/dereference at all here */ 07646 if (sipdebug) 07647 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 07648 07649 r->expire = -1; 07650 __sip_do_register(r); 07651 ASTOBJ_UNREF(r, sip_registry_destroy); 07652 return 0; 07653 }
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 4398 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::name, ast_channel::nativeformats, option_debug, sip_pvt::owner, ast_channel::readformat, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_PAGE2_T38SUPPORT_UDPTL, sip_pvt::t38, t38properties::t38support, sip_pvt::udptl, sip_pvt::vad, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by sip_read().
04399 { 04400 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 04401 struct ast_frame *f; 04402 04403 if (!p->rtp) { 04404 /* We have no RTP allocated for this channel */ 04405 return &ast_null_frame; 04406 } 04407 04408 switch(ast->fdno) { 04409 case 0: 04410 f = ast_rtp_read(p->rtp); /* RTP Audio */ 04411 break; 04412 case 1: 04413 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 04414 break; 04415 case 2: 04416 f = ast_rtp_read(p->vrtp); /* RTP Video */ 04417 break; 04418 case 3: 04419 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 04420 break; 04421 case 5: 04422 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 04423 break; 04424 default: 04425 f = &ast_null_frame; 04426 } 04427 /* Don't forward RFC2833 if we're not supposed to */ 04428 if (f && (f->frametype == AST_FRAME_DTMF) && 04429 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) 04430 return &ast_null_frame; 04431 04432 /* We already hold the channel lock */ 04433 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 04434 return f; 04435 04436 if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 04437 if (!(f->subclass & p->jointcapability)) { 04438 if (option_debug) { 04439 ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n", 04440 ast_getformatname(f->subclass), p->owner->name); 04441 } 04442 return &ast_null_frame; 04443 } 04444 if (option_debug) 04445 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 04446 p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; 04447 ast_set_read_format(p->owner, p->owner->readformat); 04448 ast_set_write_format(p->owner, p->owner->writeformat); 04449 } 04450 04451 if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 04452 f = ast_dsp_process(p->owner, p->vad, f); 04453 if (f && f->frametype == AST_FRAME_DTMF) { 04454 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') { 04455 if (option_debug) 04456 ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name); 04457 *faxdetect = 1; 04458 } else if (option_debug) { 04459 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 04460 } 04461 } 04462 } 04463 04464 return f; 04465 }
static void sip_scheddestroy | ( | struct sip_pvt * | p, | |
int | ms | |||
) | [static] |
Schedule destruction of SIP dialog.
Definition at line 2155 of file chan_sip.c.
References __sip_autodestruct(), append_history, ast_sched_add(), AST_SCHED_DEL, ast_test_flag, ast_verbose(), sip_pvt::callid, sip_pvt::flags, sip_pvt::method, sched, sip_debug_test_pvt(), sip_methods, SIP_NO_HISTORY, and sip_pvt::timer_t1.
Referenced by __sip_autodestruct(), 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().
02156 { 02157 if (ms < 0) { 02158 if (p->timer_t1 == 0) 02159 p->timer_t1 = 500; /* Set timer T1 if not set (RFC 3261) */ 02160 ms = p->timer_t1 * 64; 02161 } 02162 if (sip_debug_test_pvt(p)) 02163 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 02164 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 02165 append_history(p, "SchedDestroy", "%d ms", ms); 02166 02167 AST_SCHED_DEL(sched, p->autokillid); 02168 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 02169 }
static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 18732 of file chan_sip.c.
References ast_sched_add(), AST_SCHED_DEL, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, regl, sched, and sip_reregister().
Referenced by load_module(), and sip_do_reload().
18733 { 18734 int ms; 18735 int regspacing; 18736 if (!regobjs) 18737 return; 18738 regspacing = default_expiry * 1000/regobjs; 18739 if (regspacing > 100) 18740 regspacing = 100; 18741 ms = regspacing; 18742 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 18743 ASTOBJ_WRLOCK(iterator); 18744 AST_SCHED_DEL(sched, iterator->expire); 18745 ms += regspacing; 18746 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 18747 ASTOBJ_UNLOCK(iterator); 18748 } while (0) 18749 ); 18750 }
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 16254 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().
16255 { 16256 /* Called with peerl lock, but releases it */ 16257 struct sip_pvt *p; 16258 int newmsgs, oldmsgs; 16259 16260 /* Do we have an IP address? If not, skip this peer */ 16261 if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 16262 return 0; 16263 16264 /* Check for messages */ 16265 ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs); 16266 16267 peer->lastmsgcheck = time(NULL); 16268 16269 /* Return now if it's the same thing we told them last time */ 16270 if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) { 16271 return 0; 16272 } 16273 16274 16275 peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)); 16276 16277 if (peer->mwipvt) { 16278 /* Base message on subscription */ 16279 p = peer->mwipvt; 16280 } else { 16281 /* Build temporary dialog for this message */ 16282 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 16283 return -1; 16284 if (create_addr_from_peer(p, peer)) { 16285 /* Maybe they're not registered, etc. */ 16286 sip_destroy(p); 16287 return 0; 16288 } 16289 /* Recalculate our side, and recalculate Call ID */ 16290 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16291 p->ourip = __ourip; 16292 build_via(p); 16293 build_callid_pvt(p); 16294 /* Destroy this session after 32 secs */ 16295 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16296 } 16297 /* Send MWI */ 16298 ast_set_flag(&p->flags[0], SIP_OUTGOING); 16299 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 16300 return 0; 16301 }
static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 3891 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.
03892 { 03893 struct sip_pvt *p = ast->tech_pvt; 03894 int res = 0; 03895 03896 ast_mutex_lock(&p->lock); 03897 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03898 case SIP_DTMF_INBAND: 03899 res = -1; /* Tell Asterisk to generate inband indications */ 03900 break; 03901 case SIP_DTMF_RFC2833: 03902 if (p->rtp) 03903 ast_rtp_senddigit_begin(p->rtp, digit); 03904 break; 03905 default: 03906 break; 03907 } 03908 ast_mutex_unlock(&p->lock); 03909 03910 return res; 03911 }
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 3915 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().
03916 { 03917 struct sip_pvt *p = ast->tech_pvt; 03918 int res = 0; 03919 03920 ast_mutex_lock(&p->lock); 03921 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03922 case SIP_DTMF_INFO: 03923 transmit_info_with_digit(p, digit, duration); 03924 break; 03925 case SIP_DTMF_RFC2833: 03926 if (p->rtp) 03927 ast_rtp_senddigit_end(p->rtp, digit); 03928 break; 03929 case SIP_DTMF_INBAND: 03930 res = -1; /* Tell Asterisk to stop inband indications */ 03931 break; 03932 } 03933 ast_mutex_unlock(&p->lock); 03934 03935 return res; 03936 }
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 2415 of file chan_sip.c.
References ast_strlen_zero(), ast_verbose(), debug, ast_channel::name, sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().
02416 { 02417 struct sip_pvt *p = ast->tech_pvt; 02418 int debug = sip_debug_test_pvt(p); 02419 02420 if (debug) 02421 ast_verbose("Sending text %s on %s\n", text, ast->name); 02422 if (!p) 02423 return -1; 02424 if (ast_strlen_zero(text)) 02425 return 0; 02426 if (debug) 02427 ast_verbose("Really sending text %s on %s\n", text, ast->name); 02428 transmit_message_with_text(p, text); 02429 return 0; 02430 }
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 18459 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::callid, sip_pvt::capability, sip_pvt::flags, sip_pvt::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, SIP_ALREADYGONE, SIP_CAN_REINVITE_NAT, SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), sip_pvt::vredirip, and sip_pvt::vrtp.
Referenced by sip_fixup().
18460 { 18461 struct sip_pvt *p; 18462 int changed = 0; 18463 18464 p = chan->tech_pvt; 18465 if (!p) 18466 return -1; 18467 18468 /* Disable early RTP bridge */ 18469 if (chan->_state != AST_STATE_UP && !global_directrtpsetup) /* We are in early state */ 18470 return 0; 18471 18472 ast_mutex_lock(&p->lock); 18473 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 18474 /* If we're destroyed, don't bother */ 18475 ast_mutex_unlock(&p->lock); 18476 return 0; 18477 } 18478 18479 /* if this peer cannot handle reinvites of the media stream to devices 18480 that are known to be behind a NAT, then stop the process now 18481 */ 18482 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 18483 ast_mutex_unlock(&p->lock); 18484 return 0; 18485 } 18486 18487 if (rtp) { 18488 changed |= ast_rtp_get_peer(rtp, &p->redirip); 18489 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 18490 memset(&p->redirip, 0, sizeof(p->redirip)); 18491 changed = 1; 18492 } 18493 if (vrtp) { 18494 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 18495 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 18496 memset(&p->vredirip, 0, sizeof(p->vredirip)); 18497 changed = 1; 18498 } 18499 if (codecs) { 18500 if ((p->redircodecs != codecs)) { 18501 p->redircodecs = codecs; 18502 changed = 1; 18503 } 18504 if ((p->capability & codecs) != p->capability) { 18505 p->jointcapability &= codecs; 18506 p->capability &= codecs; 18507 changed = 1; 18508 } 18509 } 18510 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 18511 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 18512 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 18513 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 18514 if (option_debug) 18515 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)); 18516 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 18517 if (option_debug > 2) { 18518 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)); 18519 } 18520 transmit_reinvite_with_sdp(p); 18521 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18522 if (option_debug > 2) { 18523 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)); 18524 } 18525 /* We have a pending Invite. Send re-invite when we're done with the invite */ 18526 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18527 } 18528 } 18529 /* Reset lastrtprx timer */ 18530 p->lastrtprx = p->lastrtptx = time(NULL); 18531 ast_mutex_unlock(&p->lock); 18532 return 0; 18533 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 18286 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_udptl_get_peer(), sip_pvt::callid, sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, sip_pvt::ourip, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), sip_pvt::udptl, and sip_pvt::udptlredirip.
18287 { 18288 struct sip_pvt *p; 18289 18290 p = chan->tech_pvt; 18291 if (!p) 18292 return -1; 18293 ast_mutex_lock(&p->lock); 18294 if (udptl) 18295 ast_udptl_get_peer(udptl, &p->udptlredirip); 18296 else 18297 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18298 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 18299 if (!p->pendinginvite) { 18300 if (option_debug > 2) { 18301 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); 18302 } 18303 transmit_reinvite_with_t38_sdp(p); 18304 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18305 if (option_debug > 2) { 18306 ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's 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); 18307 } 18308 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18309 } 18310 } 18311 /* Reset lastrtprx timer */ 18312 p->lastrtprx = p->lastrtptx = time(NULL); 18313 ast_mutex_unlock(&p->lock); 18314 return 0; 18315 }
static int sip_show_channel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show details of one active dialog.
Definition at line 11266 of file chan_sip.c.
References sip_pvt::allowtransfer, ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_strlen_zero(), ast_test_flag, sip_pvt::callid, sip_pvt::capability, sip_pvt::cid_num, dtmfmode2str(), sip_pvt::flags, sip_route::hop, iflist, iflock, sip_pvt::jointcapability, sip_pvt::lastmsg, len(), sip_pvt::maxcallbitrate, ast_channel::name, nat2str(), ast_channel::nativeformats, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::peername, sip_pvt::recv, sip_pvt::redirip, RESULT_SHOWUSAGE, sip_pvt::route, sip_pvt::sa, SIP_DTMF, SIP_NAT, SIP_NEEDDESTROY, sip_options, SIP_OUTGOING, SIP_PROMISCREDIR, SIPBUFSIZE, sip_pvt::sipoptions, sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, text, sip_pvt::theirtag, transfermode2str(), sip_pvt::uri, sip_pvt::useragent, and sip_pvt::username.
11267 { 11268 struct sip_pvt *cur; 11269 size_t len; 11270 int found = 0; 11271 11272 if (argc != 4) 11273 return RESULT_SHOWUSAGE; 11274 len = strlen(argv[3]); 11275 ast_mutex_lock(&iflock); 11276 for (cur = iflist; cur; cur = cur->next) { 11277 if (!strncasecmp(cur->callid, argv[3], len)) { 11278 char formatbuf[SIPBUFSIZE/2]; 11279 ast_cli(fd,"\n"); 11280 if (cur->subscribed != NONE) 11281 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 11282 else 11283 ast_cli(fd, " * SIP Call\n"); 11284 ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 11285 ast_cli(fd, " Call-ID: %s\n", cur->callid); 11286 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 11287 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 11288 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 11289 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 11290 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 11291 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 11292 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 11293 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 11294 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 11295 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 11296 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 11297 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)" ); 11298 ast_cli(fd, " Our Tag: %s\n", cur->tag); 11299 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 11300 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 11301 if (!ast_strlen_zero(cur->username)) 11302 ast_cli(fd, " Username: %s\n", cur->username); 11303 if (!ast_strlen_zero(cur->peername)) 11304 ast_cli(fd, " Peername: %s\n", cur->peername); 11305 if (!ast_strlen_zero(cur->uri)) 11306 ast_cli(fd, " Original uri: %s\n", cur->uri); 11307 if (!ast_strlen_zero(cur->cid_num)) 11308 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 11309 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 11310 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 11311 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 11312 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 11313 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 11314 ast_cli(fd, " SIP Options: "); 11315 if (cur->sipoptions) { 11316 int x; 11317 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 11318 if (cur->sipoptions & sip_options[x].id) 11319 ast_cli(fd, "%s ", sip_options[x].text); 11320 } 11321 } else 11322 ast_cli(fd, "(none)\n"); 11323 ast_cli(fd, "\n\n"); 11324 found++; 11325 } 11326 } 11327 ast_mutex_unlock(&iflock); 11328 if (!found) 11329 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11330 return RESULT_SUCCESS; 11331 }
static int sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP channels.
Definition at line 11057 of file chan_sip.c.
References __sip_show_channels().
11058 { 11059 return __sip_show_channels(fd, argc, argv, 0); 11060 }
static int sip_show_domains | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list local domains.
Definition at line 10568 of file chan_sip.c.
References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, domain::context, domain::domain, domain_mode_to_text(), FORMAT, domain::list, domain::mode, RESULT_SUCCESS, and S_OR.
10569 { 10570 struct domain *d; 10571 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 10572 10573 if (AST_LIST_EMPTY(&domain_list)) { 10574 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 10575 return RESULT_SUCCESS; 10576 } else { 10577 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 10578 AST_LIST_LOCK(&domain_list); 10579 AST_LIST_TRAVERSE(&domain_list, d, list) 10580 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 10581 domain_mode_to_text(d->mode)); 10582 AST_LIST_UNLOCK(&domain_list); 10583 ast_cli(fd, "\n"); 10584 return RESULT_SUCCESS; 10585 } 10586 }
static int sip_show_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show history details of one dialog.
Definition at line 11334 of file chan_sip.c.
References ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock(), sip_pvt::callid, sip_pvt::history, iflist, iflock, len(), sip_pvt::next, NONE, RESULT_SHOWUSAGE, and sip_pvt::subscribed.
11335 { 11336 struct sip_pvt *cur; 11337 size_t len; 11338 int found = 0; 11339 11340 if (argc != 4) 11341 return RESULT_SHOWUSAGE; 11342 if (!recordhistory) 11343 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 11344 len = strlen(argv[3]); 11345 ast_mutex_lock(&iflock); 11346 for (cur = iflist; cur; cur = cur->next) { 11347 if (!strncasecmp(cur->callid, argv[3], len)) { 11348 struct sip_history *hist; 11349 int x = 0; 11350 11351 ast_cli(fd,"\n"); 11352 if (cur->subscribed != NONE) 11353 ast_cli(fd, " * Subscription\n"); 11354 else 11355 ast_cli(fd, " * SIP Call\n"); 11356 if (cur->history) 11357 AST_LIST_TRAVERSE(cur->history, hist, list) 11358 ast_cli(fd, "%d. %s\n", ++x, hist->event); 11359 if (x == 0) 11360 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 11361 found++; 11362 } 11363 } 11364 ast_mutex_unlock(&iflock); 11365 if (!found) 11366 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11367 return RESULT_SUCCESS; 11368 }
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 9993 of file chan_sip.c.
References ast_cli(), ast_copy_string(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, FORMAT2, peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, TRUE, and userl.
09994 { 09995 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 09996 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 09997 char ilimits[40]; 09998 char iused[40]; 09999 int showall = FALSE; 10000 10001 if (argc < 3) 10002 return RESULT_SHOWUSAGE; 10003 10004 if (argc == 4 && !strcmp(argv[3],"all")) 10005 showall = TRUE; 10006 10007 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 10008 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10009 ASTOBJ_RDLOCK(iterator); 10010 if (iterator->call_limit) 10011 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 10012 else 10013 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 10014 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 10015 if (showall || iterator->call_limit) 10016 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 10017 ASTOBJ_UNLOCK(iterator); 10018 } while (0) ); 10019 10020 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 10021 10022 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10023 ASTOBJ_RDLOCK(iterator); 10024 if (iterator->call_limit) 10025 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 10026 else 10027 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 10028 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 10029 if (showall || iterator->call_limit) 10030 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 10031 ASTOBJ_UNLOCK(iterator); 10032 } while (0) ); 10033 10034 return RESULT_SUCCESS; 10035 #undef FORMAT 10036 #undef FORMAT2 10037 }
static int sip_show_objects | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 10314 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
10315 { 10316 char tmp[256]; 10317 if (argc != 3) 10318 return RESULT_SHOWUSAGE; 10319 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 10320 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 10321 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 10322 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 10323 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 10324 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 10325 return RESULT_SUCCESS; 10326 }
static int sip_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 10620 of file chan_sip.c.
References _sip_show_peer().
10621 { 10622 return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); 10623 }
static int sip_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Show Peers command.
Definition at line 10170 of file chan_sip.c.
References _sip_show_peers().
10171 { 10172 return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); 10173 }
static int sip_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 10894 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.
10895 { 10896 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 10897 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 10898 char host[80]; 10899 char tmpdat[256]; 10900 struct tm tm; 10901 10902 10903 if (argc != 3) 10904 return RESULT_SHOWUSAGE; 10905 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 10906 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 10907 ASTOBJ_RDLOCK(iterator); 10908 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 10909 if (iterator->regtime) { 10910 ast_localtime(&iterator->regtime, &tm, NULL); 10911 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 10912 } else { 10913 tmpdat[0] = 0; 10914 } 10915 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 10916 ASTOBJ_UNLOCK(iterator); 10917 } while(0)); 10918 return RESULT_SUCCESS; 10919 #undef FORMAT 10920 #undef FORMAT2 10921 }
static int sip_show_settings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List global settings for the SIP channel.
Definition at line 10924 of file chan_sip.c.
References ast_check_realtime(), ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_test_flag, ast_tos2str(), authl, bindaddr, default_prefs, dtmfmode2str(), global_flags, nat2str(), print_codec_to_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, SIP_DTMF, SIP_NAT, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTSAVE_SYSNAME, SIP_PAGE2_RTUPDATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, SIP_USECLIENTCODE, SIP_USEREQPHONE, SIPBUFSIZE, and transfermode2str().
10925 { 10926 int realtimepeers; 10927 int realtimeusers; 10928 char codec_buf[SIPBUFSIZE]; 10929 10930 realtimepeers = ast_check_realtime("sippeers"); 10931 realtimeusers = ast_check_realtime("sipusers"); 10932 10933 if (argc != 3) 10934 return RESULT_SHOWUSAGE; 10935 ast_cli(fd, "\n\nGlobal Settings:\n"); 10936 ast_cli(fd, "----------------\n"); 10937 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 10938 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 10939 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 10940 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 10941 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 10942 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10943 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10944 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 10945 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 10946 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 10947 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 10948 ast_cli(fd, " Our auth realm %s\n", global_realm); 10949 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 10950 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 10951 ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No"); 10952 ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No"); 10953 ast_cli(fd, " User Agent: %s\n", global_useragent); 10954 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 10955 ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 10956 ast_cli(fd, " Caller ID: %s\n", default_callerid); 10957 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 10958 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 10959 ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 10960 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 10961 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 10962 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 10963 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 10964 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10965 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 10966 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 10967 #endif 10968 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 10969 if (!realtimepeers && !realtimeusers) 10970 ast_cli(fd, " SIP realtime: Disabled\n" ); 10971 else 10972 ast_cli(fd, " SIP realtime: Enabled\n" ); 10973 10974 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 10975 ast_cli(fd, "---------------------------\n"); 10976 ast_cli(fd, " Codecs: "); 10977 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 10978 ast_cli(fd, "%s\n", codec_buf); 10979 ast_cli(fd, " Codec Order: "); 10980 print_codec_to_cli(fd, &default_prefs); 10981 ast_cli(fd, "\n"); 10982 ast_cli(fd, " T1 minimum: %d\n", global_t1min); 10983 ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No"); 10984 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 10985 ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 10986 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 10987 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 10988 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 10989 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 10990 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 10991 ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); 10992 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 10993 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 10994 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 10995 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 10996 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 10997 ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No"); 10998 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 10999 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate); 11000 ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No"); 11001 ast_cli(fd, "\nDefault Settings:\n"); 11002 ast_cli(fd, "-----------------\n"); 11003 ast_cli(fd, " Context: %s\n", default_context); 11004 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 11005 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 11006 ast_cli(fd, " Qualify: %d\n", default_qualify); 11007 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 11008 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" ); 11009 ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)")); 11010 ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); 11011 ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); 11012 ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); 11013 11014 11015 if (realtimepeers || realtimeusers) { 11016 ast_cli(fd, "\nRealtime SIP Settings:\n"); 11017 ast_cli(fd, "----------------------\n"); 11018 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 11019 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 11020 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 11021 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 11022 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 11023 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 11024 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 11025 } 11026 ast_cli(fd, "\n----\n"); 11027 return RESULT_SUCCESS; 11028 }
static int sip_show_subscriptions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP subscriptions.
Definition at line 11063 of file chan_sip.c.
References __sip_show_channels().
11064 { 11065 return __sip_show_channels(fd, argc, argv, 1); 11066 }
static int sip_show_user | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one user in detail.
Definition at line 10839 of file chan_sip.c.
References sip_user::accountcode, sip_user::allowtransfer, sip_user::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_describe_caller_presentation(), ast_strlen_zero(), ASTOBJ_UNREF, sip_user::autoframing, sip_user::call_limit, sip_user::callgroup, sip_user::callingpres, sip_user::chanvars, sip_user::cid_name, sip_user::cid_num, sip_user::context, FALSE, find_user(), sip_user::ha, sip_user::language, sip_user::maxcallbitrate, sip_user::md5secret, ast_variable::name, sip_user::name, ast_variable::next, sip_user::pickupgroup, sip_user::prefs, print_codec_to_cli(), print_group(), RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_user::secret, sip_destroy_user(), transfermode2str(), TRUE, and ast_variable::value.
10840 { 10841 char cbuf[256]; 10842 struct sip_user *user; 10843 struct ast_variable *v; 10844 int load_realtime; 10845 10846 if (argc < 4) 10847 return RESULT_SHOWUSAGE; 10848 10849 /* Load from realtime storage? */ 10850 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10851 10852 user = find_user(argv[3], load_realtime); 10853 if (user) { 10854 ast_cli(fd,"\n\n"); 10855 ast_cli(fd, " * Name : %s\n", user->name); 10856 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 10857 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 10858 ast_cli(fd, " Context : %s\n", user->context); 10859 ast_cli(fd, " Language : %s\n", user->language); 10860 if (!ast_strlen_zero(user->accountcode)) 10861 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 10862 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 10863 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 10864 ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 10865 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 10866 ast_cli(fd, " Call limit : %d\n", user->call_limit); 10867 ast_cli(fd, " Callgroup : "); 10868 print_group(fd, user->callgroup, 0); 10869 ast_cli(fd, " Pickupgroup : "); 10870 print_group(fd, user->pickupgroup, 0); 10871 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 10872 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 10873 ast_cli(fd, " Codec Order : ("); 10874 print_codec_to_cli(fd, &user->prefs); 10875 ast_cli(fd, ")\n"); 10876 10877 ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No"); 10878 if (user->chanvars) { 10879 ast_cli(fd, " Variables :\n"); 10880 for (v = user->chanvars ; v ; v = v->next) 10881 ast_cli(fd, " %s = %s\n", v->name, v->value); 10882 } 10883 ast_cli(fd,"\n"); 10884 ASTOBJ_UNREF(user,sip_destroy_user); 10885 } else { 10886 ast_cli(fd,"User %s not found.\n", argv[3]); 10887 ast_cli(fd,"\n"); 10888 } 10889 10890 return RESULT_SUCCESS; 10891 }
static int sip_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 10093 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.
10094 { 10095 regex_t regexbuf; 10096 int havepattern = FALSE; 10097 10098 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 10099 10100 switch (argc) { 10101 case 5: 10102 if (!strcasecmp(argv[3], "like")) { 10103 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 10104 return RESULT_SHOWUSAGE; 10105 havepattern = TRUE; 10106 } else 10107 return RESULT_SHOWUSAGE; 10108 case 3: 10109 break; 10110 default: 10111 return RESULT_SHOWUSAGE; 10112 } 10113 10114 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 10115 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10116 ASTOBJ_RDLOCK(iterator); 10117 10118 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10119 ASTOBJ_UNLOCK(iterator); 10120 continue; 10121 } 10122 10123 ast_cli(fd, FORMAT, iterator->name, 10124 iterator->secret, 10125 iterator->accountcode, 10126 iterator->context, 10127 iterator->ha ? "Yes" : "No", 10128 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 10129 ASTOBJ_UNLOCK(iterator); 10130 } while (0) 10131 ); 10132 10133 if (havepattern) 10134 regfree(®exbuf); 10135 10136 return RESULT_SUCCESS; 10137 #undef FORMAT 10138 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 18646 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strdupa, ast_string_field_build, ast_strlen_zero(), get_header(), sip_pvt::initreq, LOG_ERROR, sip_pvt::our_contact, sip_alreadygone(), sip_scheddestroy(), SIP_TRANS_TIMEOUT, and transmit_response_reliable().
Referenced by sip_transfer().
18647 { 18648 char *cdest; 18649 char *extension, *host, *port; 18650 char tmp[80]; 18651 18652 cdest = ast_strdupa(dest); 18653 18654 extension = strsep(&cdest, "@"); 18655 host = strsep(&cdest, ":"); 18656 port = strsep(&cdest, ":"); 18657 if (ast_strlen_zero(extension)) { 18658 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 18659 return 0; 18660 } 18661 18662 /* we'll issue the redirect message here */ 18663 if (!host) { 18664 char *localtmp; 18665 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 18666 if (ast_strlen_zero(tmp)) { 18667 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 18668 return 0; 18669 } 18670 if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 18671 char lhost[80], lport[80]; 18672 memset(lhost, 0, sizeof(lhost)); 18673 memset(lport, 0, sizeof(lport)); 18674 localtmp++; 18675 /* This is okey because lhost and lport are as big as tmp */ 18676 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 18677 if (ast_strlen_zero(lhost)) { 18678 ast_log(LOG_ERROR, "Can't find the host address\n"); 18679 return 0; 18680 } 18681 host = ast_strdupa(lhost); 18682 if (!ast_strlen_zero(lport)) { 18683 port = ast_strdupa(lport); 18684 } 18685 } 18686 } 18687 18688 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 18689 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 18690 18691 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 18692 sip_alreadygone(p); 18693 return 0; 18694 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
Transfer SIP call.
Definition at line 3939 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().
03940 { 03941 struct sip_pvt *p = ast->tech_pvt; 03942 int res; 03943 03944 if (dest == NULL) /* functions below do not take a NULL */ 03945 dest = ""; 03946 ast_mutex_lock(&p->lock); 03947 if (ast->_state == AST_STATE_RING) 03948 res = sip_sipredirect(p, dest); 03949 else 03950 res = transmit_refer(p, dest); 03951 ast_mutex_unlock(&p->lock); 03952 return res; 03953 }
static int sip_uri_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
Definition at line 14159 of file chan_sip.c.
References ast_strdupa, S_OR, sip_uri_headers_cmp(), and sip_uri_params_cmp().
Referenced by handle_request_invite().
14160 { 14161 char *uri1 = ast_strdupa(input1); 14162 char *uri2 = ast_strdupa(input2); 14163 char *host1; 14164 char *host2; 14165 char *params1; 14166 char *params2; 14167 char *headers1; 14168 char *headers2; 14169 14170 /* Strip off "sip:" from the URI. We know this is present 14171 * because it was checked back in parse_request() 14172 */ 14173 strsep(&uri1, ":"); 14174 strsep(&uri2, ":"); 14175 14176 if ((host1 = strchr(uri1, '@'))) { 14177 *host1++ = '\0'; 14178 } 14179 if ((host2 = strchr(uri2, '@'))) { 14180 *host2++ = '\0'; 14181 } 14182 14183 /* Check for mismatched username and passwords. This is the 14184 * only case-sensitive comparison of a SIP URI 14185 */ 14186 if ((host1 && !host2) || 14187 (host2 && !host1) || 14188 (host1 && host2 && strcmp(uri1, uri2))) { 14189 return 1; 14190 } 14191 14192 if (!host1) 14193 host1 = uri1; 14194 if (!host2) 14195 host2 = uri2; 14196 14197 /* Strip off the parameters and headers so we can compare 14198 * host and port 14199 */ 14200 14201 if ((params1 = strchr(host1, ';'))) { 14202 *params1++ = '\0'; 14203 } 14204 if ((params2 = strchr(host2, ';'))) { 14205 *params2++ = '\0'; 14206 } 14207 14208 /* Headers come after parameters, but there may be headers without 14209 * parameters, thus the S_OR 14210 */ 14211 if ((headers1 = strchr(S_OR(params1, host1), '?'))) { 14212 *headers1++ = '\0'; 14213 } 14214 if ((headers2 = strchr(S_OR(params2, host2), '?'))) { 14215 *headers2++ = '\0'; 14216 } 14217 14218 /* Now the host/port are properly isolated. We can get by with a string comparison 14219 * because the SIP URI checking rules have some interesting exceptions that make 14220 * this possible. I will note 2 in particular 14221 * 1. hostnames which resolve to the same IP address as well as a hostname and its 14222 * IP address are not considered a match with SIP URI's. 14223 * 2. If one URI specifies a port and the other does not, then the URIs do not match. 14224 * This includes if one URI explicitly contains port 5060 and the other implies it 14225 * by not having a port specified. 14226 */ 14227 14228 if (strcasecmp(host1, host2)) { 14229 return 1; 14230 } 14231 14232 /* Headers have easier rules to follow, so do those first */ 14233 if (sip_uri_headers_cmp(headers1, headers2)) { 14234 return 1; 14235 } 14236 14237 /* And now the parameters. Ugh */ 14238 return sip_uri_params_cmp(params1, params2); 14239 }
static int sip_uri_headers_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
helper routine for sip_uri_cmp
This takes the "headers" from two SIP URIs and determines if the URIs match. The rules for headers is simple. If a header appears in one URI, then it must also appear in the other URI. The order in which the headers appear does not matter.
input1 | Headers from URI 1 | |
input2 | Headers from URI 2 |
Definition at line 14125 of file chan_sip.c.
References ast_strdupa, and ast_strlen_zero().
Referenced by sip_uri_cmp().
14126 { 14127 char *headers1 = ast_strdupa(input1); 14128 char *headers2 = ast_strdupa(input2); 14129 int zerolength1 = ast_strlen_zero(headers1); 14130 int zerolength2 = ast_strlen_zero(headers2); 14131 int different = 0; 14132 char *header1; 14133 14134 if ((zerolength1 && !zerolength2) || 14135 (zerolength2 && !zerolength1)) 14136 return 1; 14137 14138 if (zerolength1 && zerolength2) 14139 return 0; 14140 14141 /* At this point, we can definitively state that both inputs are 14142 * not zero-length. First, one more optimization. If the length 14143 * of the headers is not equal, then we definitely have no match 14144 */ 14145 if (strlen(headers1) != strlen(headers2)) { 14146 return 1; 14147 } 14148 14149 for (header1 = strsep(&headers1, "&"); header1; header1 = strsep(&headers1, "&")) { 14150 if (!strcasestr(headers2, header1)) { 14151 different = 1; 14152 break; 14153 } 14154 } 14155 14156 return different; 14157 }
static int sip_uri_params_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
helper routine for sip_uri_cmp
This takes the parameters from two SIP URIs and determines if the URIs match. The rules for parameters *suck*. Here's a breakdown 1. If a parameter appears in both URIs, then they must have the same value in order for the URIs to match 2. If one URI has a user, maddr, ttl, or method parameter, then the other URI must also have that parameter and must have the same value in order for the URIs to match 3. All other headers appearing in only one URI are not considered when determining if URIs match
input1 | Parameters from URI 1 | |
input2 | Parameters from URI 2 |
Definition at line 13998 of file chan_sip.c.
References ast_strdupa, and ast_strlen_zero().
Referenced by sip_uri_cmp().
13999 { 14000 char *params1 = ast_strdupa(input1); 14001 char *params2 = ast_strdupa(input2); 14002 char *pos1; 14003 char *pos2; 14004 int maddrmatch = 0; 14005 int ttlmatch = 0; 14006 int usermatch = 0; 14007 int methodmatch = 0; 14008 14009 /*Quick optimization. If both params are zero-length, then 14010 * they match 14011 */ 14012 if (ast_strlen_zero(params1) && ast_strlen_zero(params2)) { 14013 return 0; 14014 } 14015 14016 pos1 = params1; 14017 while (!ast_strlen_zero(pos1)) { 14018 char *name1 = pos1; 14019 char *value1 = strchr(pos1, '='); 14020 char *semicolon1 = strchr(pos1, ';'); 14021 int matched = 0; 14022 if (semicolon1) { 14023 *semicolon1++ = '\0'; 14024 } 14025 if (!value1) { 14026 goto fail; 14027 } 14028 *value1++ = '\0'; 14029 /* Checkpoint reached. We have the name and value parsed for param1 14030 * We have to duplicate params2 each time through the second loop 14031 * or else we can't search and replace the semicolons with \0 each 14032 * time 14033 */ 14034 pos2 = ast_strdupa(params2); 14035 while (!ast_strlen_zero(pos2)) { 14036 char *name2 = pos2; 14037 char *value2 = strchr(pos2, '='); 14038 char *semicolon2 = strchr(pos2, ';'); 14039 if (semicolon2) { 14040 *semicolon2++ = '\0'; 14041 } 14042 if (!value2) { 14043 goto fail; 14044 } 14045 *value2++ = '\0'; 14046 if (!strcasecmp(name1, name2)) { 14047 if (strcasecmp(value1, value2)) { 14048 goto fail; 14049 } else { 14050 matched = 1; 14051 break; 14052 } 14053 } 14054 pos2 = semicolon2; 14055 } 14056 /* Need to see if the parameter we're looking at is one of the 'must-match' parameters */ 14057 if (!strcasecmp(name1, "maddr")) { 14058 if (matched) { 14059 maddrmatch = 1; 14060 } else { 14061 goto fail; 14062 } 14063 } else if (!strcasecmp(name1, "ttl")) { 14064 if (matched) { 14065 ttlmatch = 1; 14066 } else { 14067 goto fail; 14068 } 14069 } else if (!strcasecmp(name1, "user")) { 14070 if (matched) { 14071 usermatch = 1; 14072 } else { 14073 goto fail; 14074 } 14075 } else if (!strcasecmp(name1, "method")) { 14076 if (matched) { 14077 methodmatch = 1; 14078 } else { 14079 goto fail; 14080 } 14081 } 14082 pos1 = semicolon1; 14083 } 14084 14085 /* We've made it out of that horrible O(m*n) construct and there are no 14086 * failures yet. We're not done yet, though, because params2 could have 14087 * an maddr, ttl, user, or method header and params1 did not. 14088 */ 14089 pos2 = params2; 14090 while (!ast_strlen_zero(pos2)) { 14091 char *name2 = pos2; 14092 char *value2 = strchr(pos2, '='); 14093 char *semicolon2 = strchr(pos2, ';'); 14094 if (semicolon2) { 14095 *semicolon2++ = '\0'; 14096 } 14097 if (!value2) { 14098 goto fail; 14099 } 14100 *value2++ = '\0'; 14101 if ((!strcasecmp(name2, "maddr") && !maddrmatch) || 14102 (!strcasecmp(name2, "ttl") && !ttlmatch) || 14103 (!strcasecmp(name2, "user") && !usermatch) || 14104 (!strcasecmp(name2, "method") && !methodmatch)) { 14105 goto fail; 14106 } 14107 } 14108 return 0; 14109 14110 fail: 14111 return 1; 14112 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 3764 of file chan_sip.c.
References ast_channel::_state, AST_FORMAT_AUDIO_MASK, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_new_source(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), sip_pvt::flags, ast_frame::frametype, sip_pvt::initreq, INV_EARLY_MEDIA, sip_pvt::invitestate, sip_pvt::lastrtptx, sip_pvt::lock, ast_channel::nativeformats, ast_channel::readformat, sip_pvt::rtp, SIP_OUTGOING, SIP_PROGRESS_SENT, ast_frame::subclass, ast_channel::tech_pvt, transmit_response_with_sdp(), sip_pvt::udptl, sip_pvt::vrtp, ast_channel::writeformat, and XMIT_UNRELIABLE.
03765 { 03766 struct sip_pvt *p = ast->tech_pvt; 03767 int res = 0; 03768 03769 switch (frame->frametype) { 03770 case AST_FRAME_VOICE: 03771 if (!(frame->subclass & ast->nativeformats)) { 03772 char s1[512], s2[512], s3[512]; 03773 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n", 03774 frame->subclass, 03775 ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK), 03776 ast->nativeformats & AST_FORMAT_AUDIO_MASK, 03777 ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat), 03778 ast->readformat, 03779 ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat), 03780 ast->writeformat); 03781 return 0; 03782 } 03783 if (p) { 03784 ast_mutex_lock(&p->lock); 03785 if (p->rtp) { 03786 /* If channel is not up, activate early media session */ 03787 if ((ast->_state != AST_STATE_UP) && 03788 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03789 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03790 ast_rtp_new_source(p->rtp); 03791 p->invitestate = INV_EARLY_MEDIA; 03792 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03793 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03794 } 03795 p->lastrtptx = time(NULL); 03796 res = ast_rtp_write(p->rtp, frame); 03797 } 03798 ast_mutex_unlock(&p->lock); 03799 } 03800 break; 03801 case AST_FRAME_VIDEO: 03802 if (p) { 03803 ast_mutex_lock(&p->lock); 03804 if (p->vrtp) { 03805 /* Activate video early media */ 03806 if ((ast->_state != AST_STATE_UP) && 03807 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03808 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03809 p->invitestate = INV_EARLY_MEDIA; 03810 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03811 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03812 } 03813 p->lastrtptx = time(NULL); 03814 res = ast_rtp_write(p->vrtp, frame); 03815 } 03816 ast_mutex_unlock(&p->lock); 03817 } 03818 break; 03819 case AST_FRAME_IMAGE: 03820 return 0; 03821 break; 03822 case AST_FRAME_MODEM: 03823 if (p) { 03824 ast_mutex_lock(&p->lock); 03825 /* UDPTL requires two-way communication, so early media is not needed here. 03826 we simply forget the frames if we get modem frames before the bridge is up. 03827 Fax will re-transmit. 03828 */ 03829 if (p->udptl && ast->_state == AST_STATE_UP) 03830 res = ast_udptl_write(p->udptl, frame); 03831 ast_mutex_unlock(&p->lock); 03832 } 03833 break; 03834 default: 03835 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 03836 return 0; 03837 } 03838 03839 return res; 03840 }
static int sipsock_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Read data from SIP socket.
Definition at line 16102 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_SCHED_DEL, ast_set_flag, ast_test_flag, ast_update_use_count(), ast_verbose(), errno, find_call(), find_sip_method(), sip_pvt::flags, get_header(), handle_request(), len(), sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, lws2sws(), netlock, option_debug, sip_pvt::owner, parse_request(), process_request_queue(), queue_request(), sip_pvt::recv, S_OR, sched, SIP_ACK, sip_debug_test_addr(), SIP_NO_HISTORY, SIP_PAGE2_TCP, SIP_PKT_DEBUG, sipsock, and transmit_response().
Referenced by do_monitor(), and siptcpsock_accept().
16103 { 16104 struct sip_request req; 16105 struct sockaddr_in sin = { 0, }; 16106 struct sip_pvt *p; 16107 int res; 16108 socklen_t len = sizeof(sin); 16109 int nounlock = 0; 16110 int recount = 0; 16111 int lockretry; 16112 16113 memset(&req, 0, sizeof(req)); 16114 if (fd == sipsock) 16115 res = recvfrom(fd, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 16116 else { 16117 if (getpeername(fd, (struct sockaddr *)&sin, &len) < 0) { 16118 close(fd); 16119 return 1; 16120 } 16121 if ((res = read(fd, req.data, sizeof(req.data) - 1)) == 0) { 16122 close(fd); 16123 return 1; 16124 } 16125 } 16126 if (res < 0) { 16127 #if !defined(__FreeBSD__) 16128 if (errno == EAGAIN) 16129 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 16130 else 16131 #endif 16132 if (errno != ECONNREFUSED) 16133 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 16134 return 1; 16135 } 16136 if (option_debug && res == sizeof(req.data) - 1) 16137 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 16138 16139 req.data[res] = '\0'; 16140 req.len = res; 16141 if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */ 16142 ast_set_flag(&req, SIP_PKT_DEBUG); 16143 if (pedanticsipchecking) 16144 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 16145 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 16146 ast_verbose("\n<--- SIP read from %s:%d:%s --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), 16147 fd == sipsock ? "UDP" : "TCP",req.data); 16148 16149 if(parse_request(&req) == -1) /* Bad packet, can't parse */ 16150 return 1; 16151 16152 req.method = find_sip_method(req.rlPart1); 16153 16154 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 16155 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 16156 16157 if (req.headers < 2) /* Must have at least two headers */ 16158 return 1; 16159 16160 /* Process request, with netlock held, and with usual deadlock avoidance */ 16161 for (lockretry = 10; lockretry > 0; lockretry--) { 16162 ast_mutex_lock(&netlock); 16163 16164 /* Find the active SIP dialog or create a new one */ 16165 p = find_call(&req, &sin, req.method); /* returns p locked */ 16166 if (p == NULL) { 16167 if (option_debug) 16168 ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len); 16169 ast_mutex_unlock(&netlock); 16170 return 1; 16171 } 16172 /* Go ahead and lock the owner if it has one -- we may need it */ 16173 /* because this is deadlock-prone, we need to try and unlock if failed */ 16174 if (!p->owner || !ast_channel_trylock(p->owner)) 16175 break; /* locking succeeded */ 16176 if (lockretry != 1) { 16177 ast_mutex_unlock(&p->lock); 16178 ast_mutex_unlock(&netlock); 16179 /* Sleep for a very short amount of time */ 16180 usleep(1); 16181 } 16182 } 16183 p->recv = sin; 16184 16185 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */ 16186 append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2); 16187 16188 if (!lockretry) { 16189 if (!queue_request(p, &req)) { 16190 /* the request has been queued for later handling */ 16191 ast_mutex_unlock(&p->lock); 16192 ast_mutex_unlock(&netlock); 16193 return 1; 16194 } 16195 16196 /* This is unsafe, since p->owner is not locked. */ 16197 if (p->owner) 16198 ast_log(LOG_ERROR, "Channel lock for %s could not be obtained, and request was unable to be queued.\n", S_OR(p->owner->name, "- no channel name ??? - ")); 16199 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 16200 if (req.method != SIP_ACK) 16201 transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */ 16202 /* XXX We could add retry-after to make sure they come back */ 16203 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 16204 ast_mutex_unlock(&p->lock); 16205 ast_mutex_unlock(&netlock); 16206 return 1; 16207 } 16208 16209 /* Is this a TCP connection ?? if so set the socket accordingly*/ 16210 if (fd != sipsock) { 16211 p->sockfd=fd; 16212 ast_set_flag(&p->flags[1], SIP_PAGE2_TCP); 16213 } else { 16214 p->sockfd=-1; 16215 } 16216 16217 /* if there are queued requests on this sip_pvt, process them first, so that everything is 16218 handled in order 16219 */ 16220 if (!AST_LIST_EMPTY(&p->request_queue)) { 16221 AST_SCHED_DEL(sched, p->request_queue_sched_id); 16222 process_request_queue(p, &recount, &nounlock); 16223 } 16224 16225 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 16226 /* Request failed */ 16227 if (option_debug) 16228 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 16229 } 16230 16231 if (p->owner && !nounlock) 16232 ast_channel_unlock(p->owner); 16233 ast_mutex_unlock(&p->lock); 16234 ast_mutex_unlock(&netlock); 16235 if (recount) 16236 ast_update_use_count(); 16237 16238 return 1; 16239 }
static int siptcpsock_accept | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Accept incoming TCP connections.
Definition at line 16242 of file chan_sip.c.
References ast_io_add(), AST_IO_IN, io, sipsock_read(), and siptcpsock.
Referenced by do_monitor().
16243 { 16244 struct sockaddr_in sa; 16245 socklen_t sa_len=sizeof(sa); 16246 int newfd; 16247 16248 if ((newfd=accept(siptcpsock, (struct sockaddr *)&sa, &sa_len)) >= 0) 16249 ast_io_add(io, newfd, sipsock_read, AST_IO_IN, NULL); 16250 return 1; 16251 }
static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 12923 of file chan_sip.c.
References ast_rtp_stop(), ast_udptl_stop(), sip_pvt::rtp, sip_pvt::udptl, and sip_pvt::vrtp.
Referenced by handle_request_bye(), handle_request_cancel(), handle_response(), and sip_hangup().
12924 { 12925 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12926 if (p->rtp) 12927 ast_rtp_stop(p->rtp); 12928 if (p->vrtp) 12929 ast_rtp_stop(p->vrtp); 12930 if (p->udptl) 12931 ast_udptl_stop(p->udptl); 12932 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 11031 of file chan_sip.c.
References subscription_types, and type.
Referenced by sip_show_channel().
11032 { 11033 int i; 11034 11035 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 11036 if (subscription_types[i].type == subtype) { 11037 return subscription_types[i].text; 11038 } 11039 } 11040 return subscription_types[0].text; 11041 }
static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 6439 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().
06440 { 06441 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 06442 06443 if (maxrate & T38FAX_RATE_14400) { 06444 if (option_debug > 1) 06445 ast_log(LOG_DEBUG, "T38MaxBitRate 14400 found\n"); 06446 return 14400; 06447 } else if (maxrate & T38FAX_RATE_12000) { 06448 if (option_debug > 1) 06449 ast_log(LOG_DEBUG, "T38MaxBitRate 12000 found\n"); 06450 return 12000; 06451 } else if (maxrate & T38FAX_RATE_9600) { 06452 if (option_debug > 1) 06453 ast_log(LOG_DEBUG, "T38MaxBitRate 9600 found\n"); 06454 return 9600; 06455 } else if (maxrate & T38FAX_RATE_7200) { 06456 if (option_debug > 1) 06457 ast_log(LOG_DEBUG, "T38MaxBitRate 7200 found\n"); 06458 return 7200; 06459 } else if (maxrate & T38FAX_RATE_4800) { 06460 if (option_debug > 1) 06461 ast_log(LOG_DEBUG, "T38MaxBitRate 4800 found\n"); 06462 return 4800; 06463 } else if (maxrate & T38FAX_RATE_2400) { 06464 if (option_debug > 1) 06465 ast_log(LOG_DEBUG, "T38MaxBitRate 2400 found\n"); 06466 return 2400; 06467 } else { 06468 if (option_debug > 1) 06469 ast_log(LOG_DEBUG, "Strange, T38MaxBitRate NOT found in peers T38 SDP.\n"); 06470 return 0; 06471 } 06472 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 17315 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ast_set_flag, ASTOBJ_INIT, default_prefs, reg_source_db(), set_peer_defaults(), SIP_PAGE2_DYNAMIC, and SIP_PAGE2_SELFDESTRUCT.
Referenced by register_verify().
17316 { 17317 struct sip_peer *peer; 17318 17319 if (!(peer = ast_calloc(1, sizeof(*peer)))) 17320 return NULL; 17321 17322 apeerobjs++; 17323 ASTOBJ_INIT(peer); 17324 set_peer_defaults(peer); 17325 17326 ast_copy_string(peer->name, name, sizeof(peer->name)); 17327 17328 ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT); 17329 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 17330 peer->prefs = default_prefs; 17331 reg_source_db(peer); 17332 17333 return peer; 17334 }
static void temp_pvt_cleanup | ( | void * | ) | [static] |
Definition at line 6214 of file chan_sip.c.
References ast_string_field_free_memory, and free.
06215 { 06216 struct sip_pvt *p = data; 06217 06218 ast_string_field_free_memory(p); 06219 06220 free(data); 06221 }
static void temp_pvt_init | ( | void | ) | [static] |
static char * transfermode2str | ( | enum transfermodes | mode | ) | const [static] |
Convert transfer mode to text string.
Definition at line 10040 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().
10041 { 10042 if (mode == TRANSFER_OPENFORALL) 10043 return "open"; 10044 else if (mode == TRANSFER_CLOSED) 10045 return "closed"; 10046 return "strict"; 10047 }
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 8847 of file chan_sip.c.
References ast_random(), ast_string_field_build, sip_pvt::randdata, and transmit_response_with_auth().
Referenced by handle_request_invite(), handle_request_subscribe(), and register_verify().
08848 { 08849 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08850 transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0); 08851 }
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 8003 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
08004 { 08005 struct sip_request req; 08006 08007 reqprep(&req, p, SIP_INFO, 0, 1); 08008 add_digit(&req, digit, duration); 08009 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08010 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 8013 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
08014 { 08015 struct sip_request req; 08016 08017 reqprep(&req, p, SIP_INFO, 0, 1); 08018 add_vidupdate(&req); 08019 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08020 }
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 7249 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_sdp(), add_t38_sdp(), sip_invite_param::addsipheaders, ALLOWED_METHODS, append_date(), ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), ast_udptl_offered_from_local(), ast_var_name(), ast_var_value(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::branch, build_via(), ast_var_t::entries, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::invite_branch, sip_pvt::lastinvite, LOG_DEBUG, sip_request::method, ast_channel::name, sip_pvt::ocseq, option_debug, sip_pvt::options, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_to, sip_refer::referred_by, sip_refer::referred_by_name, sip_invite_param::replaces, reqprep(), sip_pvt::rtp, send_request(), SIP_REFER, SIPBUFSIZE, sipdebug, t38properties::state, SUPPORTED_EXTENSIONS, sip_pvt::t38, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, sip_pvt::udptl, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.
Referenced by do_proxy_auth(), sip_call(), and sip_poke_peer().
07250 { 07251 struct sip_request req; 07252 07253 req.method = sipmethod; 07254 if (init) { /* Seems like init always is 2 */ 07255 /* Bump branch even on initial requests */ 07256 p->branch ^= ast_random(); 07257 p->invite_branch = p->branch; 07258 build_via(p); 07259 if (init > 1) 07260 initreqprep(&req, p, sipmethod); 07261 else 07262 reqprep(&req, p, sipmethod, 0, 1); 07263 } else 07264 reqprep(&req, p, sipmethod, 0, 1); 07265 07266 if (p->options && p->options->auth) 07267 add_header(&req, p->options->authheader, p->options->auth); 07268 append_date(&req); 07269 if (sipmethod == SIP_REFER) { /* Call transfer */ 07270 if (p->refer) { 07271 char buf[SIPBUFSIZE]; 07272 if (!ast_strlen_zero(p->refer->refer_to)) 07273 add_header(&req, "Refer-To", p->refer->refer_to); 07274 if (!ast_strlen_zero(p->refer->referred_by)) { 07275 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 07276 add_header(&req, "Referred-By", buf); 07277 } 07278 } 07279 } 07280 /* This new INVITE is part of an attended transfer. Make sure that the 07281 other end knows and replace the current call with this new call */ 07282 if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) { 07283 add_header(&req, "Replaces", p->options->replaces); 07284 add_header(&req, "Require", "replaces"); 07285 } 07286 07287 add_header(&req, "Allow", ALLOWED_METHODS); 07288 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07289 if (p->options && p->options->addsipheaders && p->owner) { 07290 struct ast_channel *chan = p->owner; /* The owner channel */ 07291 struct varshead *headp; 07292 07293 ast_channel_lock(chan); 07294 07295 headp = &chan->varshead; 07296 07297 if (!headp) 07298 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 07299 else { 07300 const struct ast_var_t *current; 07301 AST_LIST_TRAVERSE(headp, current, entries) { 07302 /* SIPADDHEADER: Add SIP header to outgoing call */ 07303 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 07304 char *content, *end; 07305 const char *header = ast_var_value(current); 07306 char *headdup = ast_strdupa(header); 07307 07308 /* Strip of the starting " (if it's there) */ 07309 if (*headdup == '"') 07310 headdup++; 07311 if ((content = strchr(headdup, ':'))) { 07312 *content++ = '\0'; 07313 content = ast_skip_blanks(content); /* Skip white space */ 07314 /* Strip the ending " (if it's there) */ 07315 end = content + strlen(content) -1; 07316 if (*end == '"') 07317 *end = '\0'; 07318 07319 add_header(&req, headdup, content); 07320 if (sipdebug) 07321 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 07322 } 07323 } 07324 } 07325 } 07326 07327 ast_channel_unlock(chan); 07328 } 07329 if (sdp) { 07330 if (p->udptl && (p->t38.state == T38_LOCAL_DIRECT || p->t38.state == T38_LOCAL_REINVITE)) { 07331 ast_udptl_offered_from_local(p->udptl, 1); 07332 if (option_debug) 07333 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 07334 add_t38_sdp(&req, p); 07335 } else if (p->rtp) 07336 add_sdp(&req, p); 07337 } else { 07338 add_header_contentLength(&req, 0); 07339 } 07340 07341 if (!p->initreq.headers || init > 2) 07342 initialize_initreq(p, &req); 07343 p->lastinvite = p->ocseq; 07344 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 07345 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 7912 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().
07913 { 07914 struct sip_request req; 07915 07916 reqprep(&req, p, SIP_MESSAGE, 0, 1); 07917 add_text(&req, text); 07918 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07919 }
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 7536 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_pvt::fromdomain, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::ocseq, sip_pvt::ourip, S_OR, send_request(), SIP_NOTIFY, SIP_PAGE2_BUGGY_MWI, sip_pvt::subscribed, t, and XMIT_RELIABLE.
Referenced by sip_send_mwi_to_peer().
07537 { 07538 struct sip_request req; 07539 char tmp[500]; 07540 char *t = tmp; 07541 size_t maxbytes = sizeof(tmp); 07542 07543 initreqprep(&req, p, SIP_NOTIFY); 07544 add_header(&req, "Event", "message-summary"); 07545 add_header(&req, "Content-Type", default_notifymime); 07546 07547 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 07548 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 07549 S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 07550 /* Cisco has a bug in the SIP stack where it can't accept the 07551 (0/0) notification. This can temporarily be disabled in 07552 sip.conf with the "buggymwi" option */ 07553 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)")); 07554 07555 if (p->subscribed) { 07556 if (p->expiry) 07557 add_header(&req, "Subscription-State", "active"); 07558 else /* Expired */ 07559 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07560 } 07561 07562 if (t > tmp + sizeof(tmp)) 07563 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07564 07565 add_header_contentLength(&req, strlen(tmp)); 07566 add_line(&req, tmp); 07567 07568 if (!p->initreq.headers) 07569 initialize_initreq(p, &req); 07570 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07571 }
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 7582 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ALLOWED_METHODS, sip_request::headers, initialize_initreq(), sip_pvt::initreq, sip_pvt::lastnoninvite, sip_pvt::ocseq, reqprep(), send_request(), SIP_NOTIFY, SIPBUFSIZE, SUPPORTED_EXTENSIONS, and XMIT_RELIABLE.
Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().
07583 { 07584 struct sip_request req; 07585 char tmp[SIPBUFSIZE/2]; 07586 07587 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07588 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 07589 add_header(&req, "Event", tmp); 07590 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 07591 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 07592 add_header(&req, "Allow", ALLOWED_METHODS); 07593 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07594 07595 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 07596 add_header_contentLength(&req, strlen(tmp)); 07597 add_line(&req, tmp); 07598 07599 if (!p->initreq.headers) 07600 initialize_initreq(p, &req); 07601 07602 p->lastnoninvite = p->ocseq; 07603 07604 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07605 }
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 7933 of file chan_sip.c.
References add_header(), ALLOWED_METHODS, ast_copy_string(), ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, sip_pvt::callid, sip_pvt::flags, get_header(), get_in_brackets(), sip_request::headers, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, sip_pvt::ocseq, option_debug, sip_pvt::our_contact, sip_pvt::refer, REFER_SENT, sip_refer::refer_to, sip_refer::referred_by, reqprep(), send_request(), SIP_OUTGOING, SIP_REFER, sip_refer_allocate(), sipdebug, sip_refer::status, SUPPORTED_EXTENSIONS, sip_pvt::tag, sip_pvt::theirtag, and XMIT_RELIABLE.
Referenced by sip_transfer().
07934 { 07935 struct sip_request req = { 07936 .headers = 0, 07937 }; 07938 char from[256]; 07939 const char *of; 07940 char *c; 07941 char referto[256]; 07942 char *ttag, *ftag; 07943 char *theirtag = ast_strdupa(p->theirtag); 07944 07945 if (option_debug || sipdebug) 07946 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 07947 07948 /* Are we transfering an inbound or outbound call ? */ 07949 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07950 of = get_header(&p->initreq, "To"); 07951 ttag = theirtag; 07952 ftag = p->tag; 07953 } else { 07954 of = get_header(&p->initreq, "From"); 07955 ftag = theirtag; 07956 ttag = p->tag; 07957 } 07958 07959 ast_copy_string(from, of, sizeof(from)); 07960 of = get_in_brackets(from); 07961 ast_string_field_set(p, from, of); 07962 if (strncasecmp(of, "sip:", 4)) 07963 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 07964 else 07965 of += 4; 07966 /* Get just the username part */ 07967 if ((c = strchr(dest, '@'))) 07968 c = NULL; 07969 else if ((c = strchr(of, '@'))) 07970 *c++ = '\0'; 07971 if (c) 07972 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 07973 else 07974 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 07975 07976 /* save in case we get 407 challenge */ 07977 sip_refer_allocate(p); 07978 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 07979 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 07980 p->refer->status = REFER_SENT; /* Set refer status */ 07981 07982 reqprep(&req, p, SIP_REFER, 0, 1); 07983 07984 add_header(&req, "Refer-To", referto); 07985 add_header(&req, "Allow", ALLOWED_METHODS); 07986 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07987 if (!ast_strlen_zero(p->our_contact)) 07988 add_header(&req, "Referred-By", p->our_contact); 07989 07990 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07991 /* We should propably wait for a NOTIFY here until we ack the transfer */ 07992 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 07993 07994 /*! \todo In theory, we should hang around and wait for a reply, before 07995 returning to the dial plan here. Don't know really how that would 07996 affect the transfer() app or the pbx, but, well, to make this 07997 useful we should have a STATUS code on transfer(). 07998 */ 07999 }
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 7709 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, sip_pvt::authname, sip_registry::authuser, bindaddr, sip_pvt::branch, build_callid_registry(), build_contact(), build_reply_digest(), build_via(), sip_registry::call, sip_pvt::callid, sip_registry::callid, sip_registry::callid_valid, sip_registry::contact, create_addr(), DEFAULT_MAX_FORWARDS, sip_registry::domain, exten, sip_pvt::flags, sip_pvt::fromdomain, sip_pvt::fromuser, sip_request::headers, sip_registry::hostname, init_req(), initialize_initreq(), sip_pvt::initreq, sip_request::lines, LOG_DEBUG, LOG_NOTICE, make_our_tag(), sip_registry::md5secret, sip_pvt::nonce, sip_registry::nonce, sip_pvt::noncecount, sip_registry::noncecount, sip_pvt::ocseq, sip_registry::ocseq, sip_registry::opaque, sip_pvt::opaque, option_debug, sip_pvt::our_contact, sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_registry::portno, sip_registry::qop, sip_pvt::qop, sip_registry::realm, sip_pvt::realm, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sched, sip_registry::secret, send_request(), sip_alloc(), sip_debug_test_pvt(), sip_destroy(), sip_methods, SIP_NO_HISTORY, SIP_OUTGOING, sip_reg_timeout(), SIP_REGISTER, sipdebug, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, sip_registry::timeout, sip_pvt::tohost, TRUE, sip_pvt::uri, username, sip_registry::username, sip_pvt::via, and XMIT_CRITICAL.
Referenced by __sip_do_register(), do_register_auth(), and sip_reg_timeout().
07710 { 07711 struct sip_request req; 07712 char from[256]; 07713 char to[256]; 07714 char tmp[80]; 07715 char addr[80]; 07716 struct sip_pvt *p; 07717 char *fromdomain; 07718 07719 /* exit if we are already in process with this registrar ?*/ 07720 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 07721 if (r) { 07722 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 07723 } 07724 return 0; 07725 } 07726 07727 if (r->call) { /* We have a registration */ 07728 if (!auth) { 07729 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 07730 return 0; 07731 } else { 07732 p = r->call; 07733 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 07734 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 07735 } 07736 } else { 07737 /* Build callid for registration if we haven't registered before */ 07738 if (!r->callid_valid) { 07739 build_callid_registry(r, __ourip, default_fromdomain); 07740 r->callid_valid = TRUE; 07741 } 07742 /* Allocate SIP packet for registration */ 07743 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) { 07744 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 07745 return 0; 07746 } 07747 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07748 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 07749 /* Find address to hostname */ 07750 if (create_addr(p, r->hostname)) { 07751 /* we have what we hope is a temporary network error, 07752 * probably DNS. We need to reschedule a registration try */ 07753 sip_destroy(p); 07754 07755 if (r->timeout > -1) 07756 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 07757 else 07758 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); 07759 07760 AST_SCHED_DEL(sched, r->timeout); 07761 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07762 r->regattempts++; 07763 return 0; 07764 } 07765 /* Copy back Call-ID in case create_addr changed it */ 07766 ast_string_field_set(r, callid, p->callid); 07767 if (r->portno) { 07768 p->sa.sin_port = htons(r->portno); 07769 p->recv.sin_port = htons(r->portno); 07770 } else /* Set registry port to the port set from the peer definition/srv or default */ 07771 r->portno = ntohs(p->sa.sin_port); 07772 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 07773 r->call=p; /* Save pointer to SIP packet */ 07774 p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ 07775 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 07776 ast_string_field_set(p, peersecret, r->secret); 07777 if (!ast_strlen_zero(r->md5secret)) 07778 ast_string_field_set(p, peermd5secret, r->md5secret); 07779 /* User name in this realm 07780 - if authuser is set, use that, otherwise use username */ 07781 if (!ast_strlen_zero(r->authuser)) { 07782 ast_string_field_set(p, peername, r->authuser); 07783 ast_string_field_set(p, authname, r->authuser); 07784 } else if (!ast_strlen_zero(r->username)) { 07785 ast_string_field_set(p, peername, r->username); 07786 ast_string_field_set(p, authname, r->username); 07787 ast_string_field_set(p, fromuser, r->username); 07788 } 07789 if (!ast_strlen_zero(r->username)) 07790 ast_string_field_set(p, username, r->username); 07791 /* Save extension in packet */ 07792 ast_string_field_set(p, exten, r->contact); 07793 07794 /* 07795 check which address we should use in our contact header 07796 based on whether the remote host is on the external or 07797 internal network so we can register through nat 07798 */ 07799 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 07800 p->ourip = bindaddr.sin_addr; 07801 build_contact(p); 07802 } 07803 07804 /* set up a timeout */ 07805 if (auth == NULL) { 07806 if (r->timeout > -1) 07807 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 07808 AST_SCHED_DEL(sched, r->timeout); 07809 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07810 if (option_debug) 07811 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 07812 } 07813 07814 if ((fromdomain = strchr(r->username, '@'))) { 07815 /* the domain name is just behind '@' */ 07816 fromdomain++ ; 07817 /* We have a domain in the username for registration */ 07818 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 07819 if (!ast_strlen_zero(p->theirtag)) 07820 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 07821 else 07822 snprintf(to, sizeof(to), "<sip:%s>", r->username); 07823 07824 /* If the registration username contains '@', then the domain should be used as 07825 the equivalent of "fromdomain" for the registration */ 07826 if (ast_strlen_zero(p->fromdomain)) { 07827 ast_string_field_set(p, fromdomain, fromdomain); 07828 } 07829 } else { 07830 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 07831 if (!ast_strlen_zero(p->theirtag)) 07832 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 07833 else 07834 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 07835 } 07836 07837 /* Fromdomain is what we are registering to, regardless of actual 07838 host name from SRV */ 07839 if (!ast_strlen_zero(p->fromdomain)) { 07840 if (r->portno && r->portno != STANDARD_SIP_PORT) 07841 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 07842 else 07843 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 07844 } else { 07845 if (r->portno && r->portno != STANDARD_SIP_PORT) 07846 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 07847 else 07848 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 07849 } 07850 ast_string_field_set(p, uri, addr); 07851 07852 p->branch ^= ast_random(); 07853 07854 init_req(&req, sipmethod, addr); 07855 07856 /* Add to CSEQ */ 07857 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 07858 p->ocseq = r->ocseq; 07859 07860 build_via(p); 07861 add_header(&req, "Via", p->via); 07862 add_header(&req, "From", from); 07863 add_header(&req, "To", to); 07864 add_header(&req, "Call-ID", p->callid); 07865 add_header(&req, "CSeq", tmp); 07866 if (!ast_strlen_zero(global_useragent)) 07867 add_header(&req, "User-Agent", global_useragent); 07868 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07869 07870 07871 if (auth) /* Add auth header */ 07872 add_header(&req, authheader, auth); 07873 else if (!ast_strlen_zero(r->nonce)) { 07874 char digest[1024]; 07875 07876 /* We have auth data to reuse, build a digest header! */ 07877 if (sipdebug) 07878 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 07879 ast_string_field_set(p, realm, r->realm); 07880 ast_string_field_set(p, nonce, r->nonce); 07881 ast_string_field_set(p, domain, r->domain); 07882 ast_string_field_set(p, opaque, r->opaque); 07883 ast_string_field_set(p, qop, r->qop); 07884 r->noncecount++; 07885 p->noncecount = r->noncecount; 07886 07887 memset(digest,0,sizeof(digest)); 07888 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 07889 add_header(&req, "Authorization", digest); 07890 else 07891 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 07892 07893 } 07894 07895 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 07896 add_header(&req, "Expires", tmp); 07897 add_header(&req, "Contact", p->our_contact); 07898 add_header(&req, "Event", "registration"); 07899 add_header_contentLength(&req, 0); 07900 07901 initialize_initreq(p, &req); 07902 if (sip_debug_test_pvt(p)) 07903 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 07904 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 07905 r->regattempts++; /* Another attempt */ 07906 if (option_debug > 3) 07907 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 07908 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07909 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with SDP.
Definition at line 6969 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().
06970 { 06971 struct sip_request req; 06972 06973 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06974 06975 add_header(&req, "Allow", ALLOWED_METHODS); 06976 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06977 if (sipdebug) 06978 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 06979 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 06980 append_history(p, "ReInv", "Re-invite sent"); 06981 add_sdp(&req, p); 06982 /* Use this as the basis */ 06983 initialize_initreq(p, &req); 06984 p->lastinvite = p->ocseq; 06985 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06986 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06987 }
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 6993 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().
06994 { 06995 struct sip_request req; 06996 06997 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06998 06999 add_header(&req, "Allow", ALLOWED_METHODS); 07000 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07001 if (sipdebug) 07002 add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)"); 07003 ast_udptl_offered_from_local(p->udptl, 1); 07004 add_t38_sdp(&req, p); 07005 /* Use this as the basis */ 07006 initialize_initreq(p, &req); 07007 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 07008 p->lastinvite = p->ocseq; 07009 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07010 }
static int transmit_request | ( | struct sip_pvt * | p, | |
int | sipmethod, | |||
int | inc, | |||
enum xmittype | reliable, | |||
int | newbranch | |||
) | [static] |
Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry).
Definition at line 8025 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().
08026 { 08027 struct sip_request resp; 08028 08029 if (sipmethod == SIP_ACK) 08030 p->invitestate = INV_CONFIRMED; 08031 08032 reqprep(&resp, p, sipmethod, seqno, newbranch); 08033 add_header_contentLength(&resp, 0); 08034 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 08035 }
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 8038 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(), sip_pvt::callid, ast_channel::hangupcause, sip_pvt::ocseq, sip_pvt::options, sip_pvt::owner, PROXY_AUTH, sip_pvt::realm, reqprep(), send_request(), SIP_BYE, and WWW_AUTH.
Referenced by __sip_autodestruct(), check_pendings(), and sip_hangup().
08039 { 08040 struct sip_request resp; 08041 08042 reqprep(&resp, p, sipmethod, seqno, newbranch); 08043 if (!ast_strlen_zero(p->realm)) { 08044 char digest[1024]; 08045 08046 memset(digest, 0, sizeof(digest)); 08047 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 08048 if (p->options && p->options->auth_type == PROXY_AUTH) 08049 add_header(&resp, "Proxy-Authorization", digest); 08050 else if (p->options && p->options->auth_type == WWW_AUTH) 08051 add_header(&resp, "Authorization", digest); 08052 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 08053 add_header(&resp, "Proxy-Authorization", digest); 08054 } else 08055 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 08056 } 08057 /* If we are hanging up and know a cause for that, send it in clear text to make 08058 debugging easier. */ 08059 if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) { 08060 char buf[10]; 08061 08062 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 08063 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 08064 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 08065 } 08066 08067 add_header_contentLength(&resp, 0); 08068 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 08069 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 6275 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
06276 { 06277 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06278 }
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 6294 of file chan_sip.c.
References __transmit_response(), and XMIT_CRITICAL.
Referenced by handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_subscribe(), sip_hangup(), sip_indicate(), and sip_sipredirect().
06295 { 06296 return __transmit_response(p, msg, req, XMIT_CRITICAL); 06297 }
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 6224 of file chan_sip.c.
References __ourip, __transmit_response(), ast_copy_flags, ast_log(), ast_random(), ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_reset_all, ast_string_field_set, ast_test_flag, ast_threadstorage_get(), build_via(), check_via(), do_setnat(), sip_pvt::fromdomain, global_flags, INITIAL_CSEQ, LOG_NOTICE, make_our_tag(), SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, ts_temp_pvt, and XMIT_UNRELIABLE.
06225 { 06226 struct sip_pvt *p = NULL; 06227 06228 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 06229 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 06230 return -1; 06231 } 06232 06233 /* if the structure was just allocated, initialize it */ 06234 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 06235 ast_set_flag(&p->flags[0], SIP_NO_HISTORY); 06236 if (ast_string_field_init(p, 512)) 06237 return -1; 06238 } 06239 06240 /* Initialize the bare minimum */ 06241 p->method = intended_method; 06242 06243 if (sin) { 06244 p->sa = *sin; 06245 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 06246 p->ourip = __ourip; 06247 } else 06248 p->ourip = __ourip; 06249 06250 p->branch = ast_random(); 06251 make_our_tag(p->tag, sizeof(p->tag)); 06252 p->ocseq = INITIAL_CSEQ; 06253 06254 if (useglobal_nat && sin) { 06255 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 06256 p->recv = *sin; 06257 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 06258 } 06259 check_via(p, req); 06260 06261 ast_string_field_set(p, fromdomain, default_fromdomain); 06262 build_via(p); 06263 ast_string_field_set(p, callid, callid); 06264 06265 /* Use this temporary pvt structure to send the message */ 06266 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06267 06268 /* Free the string fields, but not the pool space */ 06269 ast_string_field_reset_all(p); 06270 06271 return 0; 06272 }
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 6322 of file chan_sip.c.
References add_header(), add_header_contentLength(), respprep(), and send_response().
Referenced by handle_request(), and handle_request_options().
06323 { 06324 struct sip_request resp; 06325 respprep(&resp, p, msg, req); 06326 add_header(&resp, "Accept", "application/sdp"); 06327 add_header_contentLength(&resp, 0); 06328 return send_response(p, &resp, reliable, 0); 06329 }
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 6332 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_history, ast_log(), get_header(), sip_pvt::noncecount, respprep(), send_response(), and sip_pvt::username.
Referenced by check_auth(), and transmit_fake_auth_response().
06333 { 06334 struct sip_request resp; 06335 char tmp[512]; 06336 int seqno = 0; 06337 06338 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06339 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06340 return -1; 06341 } 06342 /* Stale means that they sent us correct authentication, but 06343 based it on an old challenge (nonce) */ 06344 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 06345 respprep(&resp, p, msg, req); 06346 add_header(&resp, header, tmp); 06347 add_header_contentLength(&resp, 0); 06348 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 06349 return send_response(p, &resp, reliable, seqno); 06350 }
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 6312 of file chan_sip.c.
References add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
06313 { 06314 struct sip_request resp; 06315 respprep(&resp, p, msg, req); 06316 append_date(&resp); 06317 add_header_contentLength(&resp, 0); 06318 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06319 }
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 6898 of file chan_sip.c.
References add_sdp(), ast_log(), ast_rtp_codec_setpref(), ast_test_flag, sip_pvt::autoframing, sip_pvt::callid, sip_pvt::flags, get_header(), LOG_DEBUG, LOG_ERROR, option_debug, sip_pvt::pendinginvite, sip_pvt::prefs, respprep(), sip_pvt::rtp, send_response(), SIP_OUTGOING, and try_suggested_sip_codec().
Referenced by handle_invite_replaces(), handle_request_invite(), sip_answer(), sip_indicate(), and sip_write().
06899 { 06900 struct sip_request resp; 06901 int seqno; 06902 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06903 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06904 return -1; 06905 } 06906 respprep(&resp, p, msg, req); 06907 if (p->rtp) { 06908 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06909 if (option_debug) 06910 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 06911 ast_rtp_codec_setpref(p->rtp, &p->prefs); 06912 } 06913 try_suggested_sip_codec(p); 06914 add_sdp(&resp, p); 06915 } else 06916 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 06917 if (reliable && !p->pendinginvite) 06918 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06919 return send_response(p, &resp, reliable, seqno); 06920 }
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 6858 of file chan_sip.c.
References add_t38_sdp(), ast_log(), ast_udptl_offered_from_local(), sip_pvt::callid, get_header(), LOG_ERROR, sip_pvt::pendinginvite, respprep(), send_response(), and sip_pvt::udptl.
Referenced by handle_request_invite(), sip_answer(), and sip_handle_t38_reinvite().
06859 { 06860 struct sip_request resp; 06861 int seqno; 06862 06863 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06864 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06865 return -1; 06866 } 06867 respprep(&resp, p, msg, req); 06868 if (p->udptl) { 06869 ast_udptl_offered_from_local(p->udptl, 0); 06870 add_t38_sdp(&resp, p); 06871 } else 06872 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 06873 if (retrans && !p->pendinginvite) 06874 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06875 return send_response(p, &resp, retrans, seqno); 06876 }
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 6281 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
06282 { 06283 struct sip_request resp; 06284 respprep(&resp, p, msg, req); 06285 append_date(&resp); 06286 add_header(&resp, "Unsupported", unsupported); 06287 add_header_contentLength(&resp, 0); 06288 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06289 }
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 7574 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().
07575 { 07576 if (!p->initreq.headers) /* Initialize first request before sending */ 07577 initialize_initreq(p, req); 07578 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 07579 }
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 7348 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_copy_string(), ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), ast_log(), AST_MAX_EXTENSION, sip_pvt::context, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, sip_pvt::expiry, sip_pvt::exten, find_subscription_type(), get_header(), get_in_brackets(), sip_pvt::initreq, NONE, sip_pvt::ocseq, sip_pvt::pendinginvite, PIDF_XML, reqprep(), send_request(), SIP_NOTIFY, sip_pvt::subscribed, t, XMIT_RELIABLE, and XPIDF_XML.
Referenced by __sip_autodestruct(), cb_extensionstate(), and handle_request_subscribe().
07349 { 07350 char tmp[4000], from[256], to[256]; 07351 char *t = tmp, *c, *mfrom, *mto; 07352 size_t maxbytes = sizeof(tmp); 07353 struct sip_request req; 07354 char hint[AST_MAX_EXTENSION]; 07355 char *statestring = "terminated"; 07356 const struct cfsubscription_types *subscriptiontype; 07357 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 07358 char *pidfstate = "--"; 07359 char *pidfnote= "Ready"; 07360 07361 memset(from, 0, sizeof(from)); 07362 memset(to, 0, sizeof(to)); 07363 memset(tmp, 0, sizeof(tmp)); 07364 07365 switch (state) { 07366 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 07367 statestring = (global_notifyringing) ? "early" : "confirmed"; 07368 local_state = NOTIFY_INUSE; 07369 pidfstate = "busy"; 07370 pidfnote = "Ringing"; 07371 break; 07372 case AST_EXTENSION_RINGING: 07373 statestring = "early"; 07374 local_state = NOTIFY_INUSE; 07375 pidfstate = "busy"; 07376 pidfnote = "Ringing"; 07377 break; 07378 case AST_EXTENSION_INUSE: 07379 statestring = "confirmed"; 07380 local_state = NOTIFY_INUSE; 07381 pidfstate = "busy"; 07382 pidfnote = "On the phone"; 07383 break; 07384 case AST_EXTENSION_BUSY: 07385 statestring = "confirmed"; 07386 local_state = NOTIFY_CLOSED; 07387 pidfstate = "busy"; 07388 pidfnote = "On the phone"; 07389 break; 07390 case AST_EXTENSION_UNAVAILABLE: 07391 statestring = "terminated"; 07392 local_state = NOTIFY_CLOSED; 07393 pidfstate = "away"; 07394 pidfnote = "Unavailable"; 07395 break; 07396 case AST_EXTENSION_ONHOLD: 07397 statestring = "confirmed"; 07398 local_state = NOTIFY_CLOSED; 07399 pidfstate = "busy"; 07400 pidfnote = "On Hold"; 07401 break; 07402 case AST_EXTENSION_NOT_INUSE: 07403 default: 07404 /* Default setting */ 07405 break; 07406 } 07407 07408 subscriptiontype = find_subscription_type(p->subscribed); 07409 07410 /* Check which device/devices we are watching and if they are registered */ 07411 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 07412 char *hint2 = hint, *individual_hint = NULL; 07413 int hint_count = 0, unavailable_count = 0; 07414 07415 while ((individual_hint = strsep(&hint2, "&"))) { 07416 hint_count++; 07417 07418 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 07419 unavailable_count++; 07420 } 07421 07422 /* If none of the hinted devices are registered, we will 07423 * override notification and show no availability. 07424 */ 07425 if (hint_count > 0 && hint_count == unavailable_count) { 07426 local_state = NOTIFY_CLOSED; 07427 pidfstate = "away"; 07428 pidfnote = "Not online"; 07429 } 07430 } 07431 07432 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 07433 c = get_in_brackets(from); 07434 if (strncasecmp(c, "sip:", 4)) { 07435 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07436 return -1; 07437 } 07438 mfrom = strsep(&c, ";"); /* trim ; and beyond */ 07439 07440 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 07441 c = get_in_brackets(to); 07442 if (strncasecmp(c, "sip:", 4)) { 07443 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07444 return -1; 07445 } 07446 mto = strsep(&c, ";"); /* trim ; and beyond */ 07447 07448 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07449 07450 07451 add_header(&req, "Event", subscriptiontype->event); 07452 add_header(&req, "Content-Type", subscriptiontype->mediatype); 07453 switch(state) { 07454 case AST_EXTENSION_DEACTIVATED: 07455 if (timeout) 07456 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07457 else { 07458 add_header(&req, "Subscription-State", "terminated;reason=probation"); 07459 add_header(&req, "Retry-After", "60"); 07460 } 07461 break; 07462 case AST_EXTENSION_REMOVED: 07463 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 07464 break; 07465 default: 07466 if (p->expiry) 07467 add_header(&req, "Subscription-State", "active"); 07468 else /* Expired */ 07469 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07470 } 07471 switch (p->subscribed) { 07472 case XPIDF_XML: 07473 case CPIM_PIDF_XML: 07474 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07475 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 07476 ast_build_string(&t, &maxbytes, "<presence>\n"); 07477 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 07478 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 07479 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 07480 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 07481 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 07482 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 07483 break; 07484 case PIDF_XML: /* Eyebeam supports this format */ 07485 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 07486 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); 07487 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 07488 if (pidfstate[0] != '-') 07489 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 07490 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 07491 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 07492 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 07493 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 07494 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 07495 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 07496 else 07497 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 07498 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 07499 break; 07500 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 07501 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07502 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); 07503 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 07504 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 07505 else 07506 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 07507 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 07508 if (state == AST_EXTENSION_ONHOLD) { 07509 ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n" 07510 "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n" 07511 "</target>\n</local>\n", mto); 07512 } 07513 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 07514 break; 07515 case NONE: 07516 default: 07517 break; 07518 } 07519 07520 if (t > tmp + sizeof(tmp)) 07521 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07522 07523 add_header_contentLength(&req, strlen(tmp)); 07524 add_line(&req, tmp); 07525 p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */ 07526 07527 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07528 }
static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 3712 of file chan_sip.c.
References ast_getformatbyname(), ast_log(), sip_pvt::capability, sip_pvt::jointcapability, LOG_NOTICE, sip_pvt::owner, and pbx_builtin_getvar_helper().
Referenced by sip_answer(), and transmit_response_with_sdp().
03713 { 03714 int fmt; 03715 const char *codec; 03716 03717 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 03718 if (!codec) 03719 return; 03720 03721 fmt = ast_getformatbyname(codec); 03722 if (fmt) { 03723 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 03724 if (p->jointcapability & fmt) { 03725 p->jointcapability &= fmt; 03726 p->capability &= fmt; 03727 } else 03728 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 03729 } else 03730 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 03731 return; 03732 }
static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 18973 of file chan_sip.c.
References __sip_destroy(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free_ha(), ast_manager_unregister(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_udptl_proto_unregister(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, checksipdomain_function, clear_realm_authentication(), clear_sip_domains(), cli_sip, iflist, iflock, localaddr, monlock, sip_pvt::next, sip_pvt::owner, peerl, regl, sched, sched_context_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_header_function, sip_registry_destroy(), sip_rtp, sip_tech, sip_udptl, sipchaninfo_function, sippeer_function, sipsock, siptcpsock, TRUE, and userl.
18974 { 18975 struct sip_pvt *p, *pl; 18976 18977 /* First, take us out of the channel type list */ 18978 ast_channel_unregister(&sip_tech); 18979 18980 /* Unregister dial plan functions */ 18981 ast_custom_function_unregister(&sipchaninfo_function); 18982 ast_custom_function_unregister(&sippeer_function); 18983 ast_custom_function_unregister(&sip_header_function); 18984 ast_custom_function_unregister(&checksipdomain_function); 18985 18986 /* Unregister dial plan applications */ 18987 ast_unregister_application(app_dtmfmode); 18988 ast_unregister_application(app_sipaddheader); 18989 18990 /* Unregister CLI commands */ 18991 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 18992 18993 /* Disconnect from the RTP subsystem */ 18994 ast_rtp_proto_unregister(&sip_rtp); 18995 18996 /* Disconnect from UDPTL */ 18997 ast_udptl_proto_unregister(&sip_udptl); 18998 18999 /* Unregister AMI actions */ 19000 ast_manager_unregister("SIPpeers"); 19001 ast_manager_unregister("SIPshowpeer"); 19002 19003 ast_mutex_lock(&iflock); 19004 /* Hangup all interfaces if they have an owner */ 19005 for (p = iflist; p ; p = p->next) { 19006 if (p->owner) 19007 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 19008 } 19009 ast_mutex_unlock(&iflock); 19010 19011 ast_mutex_lock(&monlock); 19012 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 19013 pthread_cancel(monitor_thread); 19014 pthread_kill(monitor_thread, SIGURG); 19015 pthread_join(monitor_thread, NULL); 19016 } 19017 monitor_thread = AST_PTHREADT_STOP; 19018 ast_mutex_unlock(&monlock); 19019 19020 restartdestroy: 19021 ast_mutex_lock(&iflock); 19022 /* Destroy all the interfaces and free their memory */ 19023 p = iflist; 19024 while (p) { 19025 pl = p; 19026 p = p->next; 19027 if (__sip_destroy(pl, TRUE) < 0) { 19028 /* Something is still bridged, let it react to getting a hangup */ 19029 iflist = p; 19030 ast_mutex_unlock(&iflock); 19031 usleep(1); 19032 goto restartdestroy; 19033 } 19034 } 19035 iflist = NULL; 19036 ast_mutex_unlock(&iflock); 19037 19038 /* Free memory for local network address mask */ 19039 ast_free_ha(localaddr); 19040 19041 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 19042 ASTOBJ_CONTAINER_DESTROY(&userl); 19043 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 19044 ASTOBJ_CONTAINER_DESTROY(&peerl); 19045 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 19046 ASTOBJ_CONTAINER_DESTROY(®l); 19047 19048 clear_realm_authentication(authl); 19049 clear_sip_domains(); 19050 close(sipsock); 19051 close(siptcpsock); 19052 sched_context_destroy(sched); 19053 19054 return 0; 19055 }
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 3263 of file chan_sip.c.
References ast_clear_flag, ast_copy_string(), ast_device_state_changed(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_user::call_limit, DEC_CALL_LIMIT, DEC_CALL_RINGING, FALSE, find_peer(), find_user(), sip_peer::flags, sip_pvt::flags, INC_CALL_LIMIT, INC_CALL_RINGING, sip_peer::inRinging, sip_peer::inUse, sip_user::inUse, inuse, LOG_DEBUG, LOG_ERROR, sip_peer::name, name, option_debug, sip_pvt::peername, SIP_CALL_LIMIT, sip_destroy_peer(), sip_destroy_user(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_INC_RINGING, SIP_PAGE2_OUTGOING_CALL, SIP_PAGE2_RTCACHEFRIENDS, sip_peer_hold(), SIP_REALTIME, sipdebug, and sip_pvt::username.
Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_call(), and sip_hangup().
03264 { 03265 char name[256]; 03266 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 03267 int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL); 03268 struct sip_user *u = NULL; 03269 struct sip_peer *p = NULL; 03270 03271 if (option_debug > 2) 03272 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 03273 03274 /* Test if we need to check call limits, in order to avoid 03275 realtime lookups if we do not need it */ 03276 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 03277 return 0; 03278 03279 ast_copy_string(name, fup->username, sizeof(name)); 03280 03281 /* Check the list of users only for incoming calls */ 03282 if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) { 03283 inuse = &u->inUse; 03284 call_limit = &u->call_limit; 03285 inringing = NULL; 03286 } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1, 0) ) ) { /* Try to find peer */ 03287 inuse = &p->inUse; 03288 call_limit = &p->call_limit; 03289 inringing = &p->inRinging; 03290 ast_copy_string(name, fup->peername, sizeof(name)); 03291 } 03292 if (!p && !u) { 03293 if (option_debug > 1) 03294 ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name); 03295 return 0; 03296 } 03297 03298 switch(event) { 03299 /* incoming and outgoing affects the inUse counter */ 03300 case DEC_CALL_LIMIT: 03301 if ( *inuse > 0 ) { 03302 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 03303 (*inuse)--; 03304 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 03305 } 03306 } else { 03307 *inuse = 0; 03308 } 03309 if (inringing) { 03310 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03311 if (*inringing > 0) 03312 (*inringing)--; 03313 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03314 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername); 03315 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03316 } 03317 } 03318 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) { 03319 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 03320 sip_peer_hold(fup, 0); 03321 } 03322 if (option_debug > 1 || sipdebug) { 03323 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 03324 } 03325 break; 03326 03327 case INC_CALL_RINGING: 03328 case INC_CALL_LIMIT: 03329 if (*call_limit > 0 ) { 03330 /* Let call limit affect only outgoing calls */ 03331 if (outgoing && (*inuse >= *call_limit)) { 03332 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); 03333 if (u) 03334 ASTOBJ_UNREF(u, sip_destroy_user); 03335 else 03336 ASTOBJ_UNREF(p, sip_destroy_peer); 03337 return -1; 03338 } 03339 } 03340 if (inringing && (event == INC_CALL_RINGING)) { 03341 if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03342 (*inringing)++; 03343 ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03344 } 03345 } 03346 /* Continue */ 03347 (*inuse)++; 03348 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 03349 if (option_debug > 1 || sipdebug) { 03350 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 03351 } 03352 break; 03353 03354 case DEC_CALL_RINGING: 03355 if (inringing) { 03356 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03357 if (*inringing > 0) 03358 (*inringing)--; 03359 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03360 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name); 03361 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03362 } 03363 } 03364 break; 03365 03366 default: 03367 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 03368 } 03369 if (p) { 03370 ast_device_state_changed("SIP/%s", p->name); 03371 ASTOBJ_UNREF(p, sip_destroy_peer); 03372 } else /* u must be set */ 03373 ASTOBJ_UNREF(u, sip_destroy_user); 03374 return 0; 03375 }
static void update_peer | ( | struct sip_peer * | p, | |
int | expiry | |||
) | [static] |
Update peer data in database (if used).
Definition at line 2536 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, sip_peer::fullcontact, global_flags, sip_peer::name, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_REALTIME, and sip_peer::username.
Referenced by register_verify().
02537 { 02538 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02539 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) && 02540 (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) { 02541 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry); 02542 } 02543 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Session Initiation Protocol (SIP)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 19061 of file chan_sip.c.
struct in_addr __ourip [static] |
Definition at line 1231 of file chan_sip.c.
int allow_external_domains [static] |
Accept calls to external SIP domains?
Definition at line 565 of file chan_sip.c.
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 585 of file chan_sip.c.
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 18537 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 18539 of file chan_sip.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 19061 of file chan_sip.c.
Definition at line 1219 of file chan_sip.c.
Referenced by build_reply_digest(), reload_config(), sip_show_settings(), and unload_module().
int autocreatepeer [static] |
Auto creation of peers at registration? Default off.
Definition at line 545 of file chan_sip.c.
struct sockaddr_in bindaddr = { 0, } [static] |
The address we bind to
Definition at line 1225 of file chan_sip.c.
struct ast_threadstorage check_auth_buf = { .once = PTHREAD_ONCE_INIT , .key_init = check_auth_buf_init , } [static] |
struct ast_custom_function checksipdomain_function [static] |
struct ast_cli_entry cli_sip[] [static] |
struct ast_cli_entry cli_sip_debug_deprecated [static] |
Initial value:
{ { "sip", "debug", NULL }, sip_do_debug_deprecated, "Enable SIP debugging", debug_usage }
Definition at line 18799 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 18804 of file chan_sip.c.
int compactheaders [static] |
send compact sip headers
Definition at line 559 of file chan_sip.c.
const char config[] = "sip.conf" [static] |
Definition at line 231 of file chan_sip.c.
char debug_usage[] [static] |
Definition at line 11961 of file chan_sip.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1234 of file chan_sip.c.
Referenced by sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), and sip_do_debug_peer().
char default_callerid[AST_MAX_EXTENSION] [static] |
Definition at line 525 of file chan_sip.c.
char default_context[AST_MAX_CONTEXT] [static] |
Definition at line 522 of file chan_sip.c.
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 192 of file chan_sip.c.
char default_fromdomain[AST_MAX_EXTENSION] [static] |
Definition at line 526 of file chan_sip.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled.
Definition at line 222 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Definition at line 524 of file chan_sip.c.
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 533 of file chan_sip.c.
char default_mohinterpret[MAX_MUSICCLASS] [static] |
Global setting for moh class to use when put on hold
Definition at line 530 of file chan_sip.c.
char default_mohsuggest[MAX_MUSICCLASS] [static] |
Global setting for moh class to suggest when putting a bridged channel on hold
Definition at line 531 of file chan_sip.c.
char default_notifymime[AST_MAX_EXTENSION] [static] |
Definition at line 527 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 534 of file chan_sip.c.
Referenced by build_device(), build_user(), reload_config(), set_peer_defaults(), sip_alloc(), sip_show_settings(), and temp_peer().
int default_qualify [static] |
Default Qualify= setting
Definition at line 528 of file chan_sip.c.
char default_subscribecontext[AST_MAX_CONTEXT] [static] |
Definition at line 523 of file chan_sip.c.
char default_vmexten[AST_MAX_EXTENSION] [static] |
Definition at line 529 of file chan_sip.c.
char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static] |
Definition at line 18536 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 18542 of file chan_sip.c.
int dumphistory [static] |
Dump history to verbose before destroying SIP dialog
Definition at line 561 of file chan_sip.c.
int expiry = DEFAULT_EXPIRY [static] |
Definition at line 193 of file chan_sip.c.
Referenced by complete_dpreply(), and process_clearcache().
time_t externexpire = 0 [static] |
Expiration counter for re-resolving external host name in dynamic DNS
Definition at line 1228 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor().
char externhost[MAXHOSTNAMELEN] [static] |
External host name (possibly with dynamic DNS and DHCP
Definition at line 1227 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor().
struct sockaddr_in externip [static] |
External IP address if we are behind NAT
Definition at line 1226 of file chan_sip.c.
int externrefresh = 10 [static] |
int global_allowguest [static] |
allow unauthenticated users/peers to connect?
Definition at line 552 of file chan_sip.c.
int global_allowsubscribe [static] |
Flag for disabling ALL subscriptions, this is FALSE only if all peers are FALSE the global setting is in globals_flags[1]
Definition at line 553 of file chan_sip.c.
enum transfermodes global_allowtransfer [static] |
SIP Refer restriction scheme
Definition at line 569 of file chan_sip.c.
int global_alwaysauthreject [static] |
Send 401 Unauthorized for all failing requests
Definition at line 542 of file chan_sip.c.
int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 568 of file chan_sip.c.
int global_callevents [static] |
Whether we send manager events or not
Definition at line 566 of file chan_sip.c.
int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 [static] |
struct ast_ha* global_contact_ha = NULL [static] |
Global list of addresses dynamic peers are not allowed to use.
Definition at line 577 of file chan_sip.c.
Referenced by build_peer(), parse_register_contact(), and reload_config().
int global_directrtpsetup [static] |
Enable support for Direct RTP setup (no re-invites)
Definition at line 537 of file chan_sip.c.
int global_dynamic_exclude_static = 0 [static] |
Definition at line 578 of file chan_sip.c.
struct ast_flags global_flags[2] = {{0}} [static] |
global SIP_ flags
Definition at line 588 of file chan_sip.c.
Referenced by build_peer(), build_radius_record(), build_user(), destroy_association(), get_destination(), load_module(), realtime_update_peer(), set_peer_defaults(), sip_alloc(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), sip_no_debug_deprecated(), sip_show_settings(), transmit_response_using_temp(), and update_peer().
struct ast_jb_conf global_jbconf [static] |
Definition at line 229 of file chan_sip.c.
int global_limitonpeers [static] |
Match call limit on peers only
Definition at line 538 of file chan_sip.c.
int global_matchexterniplocally [static] |
Match externip/externhost setting against localnet setting
Definition at line 571 of file chan_sip.c.
int global_mwitime [static] |
Time between MWI checks for peers
Definition at line 555 of file chan_sip.c.
int global_notifyhold [static] |
Send notifications on hold
Definition at line 541 of file chan_sip.c.
int global_notifyringing [static] |
Send notifications on ringing
Definition at line 540 of file chan_sip.c.
char global_realm[MAXHOSTNAMELEN] [static] |
Default realm
Definition at line 562 of file chan_sip.c.
int global_reg_timeout [static] |
Definition at line 550 of file chan_sip.c.
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 551 of file chan_sip.c.
char global_regcontext[AST_MAX_CONTEXT] [static] |
Context for auto-extensions
Definition at line 563 of file chan_sip.c.
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 546 of file chan_sip.c.
int global_rtautoclear [static] |
Definition at line 539 of file chan_sip.c.
int global_rtpholdtimeout [static] |
Definition at line 548 of file chan_sip.c.
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 549 of file chan_sip.c.
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 547 of file chan_sip.c.
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 567 of file chan_sip.c.
int global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 [static] |
Definition at line 843 of file chan_sip.c.
unsigned int global_tos_audio [static] |
IP type of service for audio RTP packets
Definition at line 557 of file chan_sip.c.
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 556 of file chan_sip.c.
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 558 of file chan_sip.c.
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 564 of file chan_sip.c.
char history_usage[] [static] |
Initial value:
"Usage: sip history\n" " Enables recording of SIP dialog history for debugging purposes.\n" "Use 'sip show history' to view the history of a call number.\n"
Definition at line 11978 of file chan_sip.c.
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe
ast_mutex_t iflock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
struct io_context* io [static] |
The IO context
Definition at line 609 of file chan_sip.c.
List of local networks, on the same side of NAT as this Asterisk
Definition at line 1230 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and unload_module().
char mandescr_show_peer[] [static] |
Initial value:
"Description: Show one SIP peer with details on current status.\n" "Variables: \n" " Peer: <name> The peer name you want to check.\n" " ActionID: <id> Optional action ID for this AMI transaction.\n"
Definition at line 10589 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 10140 of file chan_sip.c.
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Maximum accepted registration time
Definition at line 191 of file chan_sip.c.
int min_expiry = DEFAULT_MIN_EXPIRY [static] |
Minimum accepted registration time
Definition at line 190 of file chan_sip.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
This is the thread for the monitor which checks for input on the channels which are not currently in use.
Definition at line 603 of file chan_sip.c.
ast_mutex_t monlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Definition at line 597 of file chan_sip.c.
ast_mutex_t netlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
Definition at line 595 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 11970 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 11974 of file chan_sip.c.
const char notify_config[] = "sip_notify.conf" [static] |
Definition at line 232 of file chan_sip.c.
struct ast_config* notify_types [static] |
The list of manual NOTIFY types we know how to send
Definition at line 1236 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 11910 of file chan_sip.c.
int ourport [static] |
Definition at line 1233 of file chan_sip.c.
struct sockaddr_in outboundproxyip [static] |
Definition at line 1232 of file chan_sip.c.
int pedanticsipchecking [static] |
Extra checking ? Default off
Definition at line 544 of file chan_sip.c.
struct ast_peer_list peerl [static] |
The peer list: Peers and Friends.
char prune_realtime_usage[] [static] |
Initial value:
"Usage: sip prune realtime [peer|user] [<name>|all|like <pattern>]\n" " Prunes object(s) from the cache.\n" " Optional regular expression pattern is used to filter the objects.\n"
Definition at line 11952 of file chan_sip.c.
int recordhistory [static] |
Record SIP history. Off by default
Definition at line 560 of file chan_sip.c.
struct c_referstatusstring referstatusstrings[] [static] |
Referenced by referstatus2str().
struct ast_register_list regl [static] |
The register list: Other SIP proxys we register with and place calls to.
Referenced by load_module(), reload_config(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module().
int regobjs = 0 [static] |
Registry objects
Definition at line 586 of file chan_sip.c.
int rpeerobjs = 0 [static] |
Realtime peers
Definition at line 584 of file chan_sip.c.
int ruserobjs = 0 [static] |
Realtime users
Definition at line 582 of file chan_sip.c.
struct sched_context* sched [static] |
The scheduling context
Definition at line 608 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 11934 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 11930 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 11905 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 11938 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 11925 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 11991 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 11947 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 11942 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 11957 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 11995 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 11987 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 11920 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 11915 of file chan_sip.c.
struct ast_custom_function sip_header_function [static] |
struct cfsip_methods sip_methods[] [static] |
XXX Note that sip_methods[i].id == i must hold or the code breaks
Referenced by __sip_ack(), __sip_autodestruct(), __sip_destroy(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), check_auth(), do_proxy_auth(), find_sip_method(), get_destination(), handle_request(), handle_request_subscribe(), handle_response(), init_req(), initreqprep(), method_match(), reqprep(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_scheddestroy(), and transmit_register().
struct cfsip_options sip_options[] [static] |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly.
Referenced by _sip_show_peer(), parse_sip_options(), and sip_show_channel().
ast_mutex_t sip_reload_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
char sip_reload_usage[] [static] |
Initial value:
"Usage: sip reload\n" " Reloads SIP configuration from sip.conf\n"
Definition at line 11983 of file chan_sip.c.
int sip_reloading = FALSE [static] |
Flag for avoiding multiple reloads at the same time
Definition at line 605 of file chan_sip.c.
enum channelreloadreason sip_reloadreason [static] |
Reason for last reload/load of configuration
Definition at line 606 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 1633 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 1575 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 1601 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 1642 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 12236 of file chan_sip.c.
Referenced by load_module(), and unload_module().
Structure to declare a dialplan function: SIPPEER.
Definition at line 12156 of file chan_sip.c.
Referenced by load_module(), and unload_module().
int sipsock = -1 [static] |
Main socket for SIP network communication UDP
Definition at line 1223 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 610 of file chan_sip.c.
int siptcpsock = -1 [static] |
Main socket for SIP network communication TCP
Definition at line 1224 of file chan_sip.c.
Referenced by do_monitor(), reg_source_db(), siptcpsock_accept(), and unload_module().
int* siptcpsock_read_id [static] |
ID of IO entry for sipsock FD
Definition at line 611 of file chan_sip.c.
int speerobjs = 0 [static] |
Statis peers
Definition at line 583 of file chan_sip.c.
int srvlookup [static] |
SRV Lookup on or off. Default is on
Definition at line 543 of file chan_sip.c.
struct cfsubscription_types subscription_types[] [static] |
Referenced by find_subscription_type(), and subscription_type2str().
int suserobjs = 0 [static] |
Static users
Definition at line 581 of file chan_sip.c.
char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static] |
Definition at line 18535 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 18540 of file chan_sip.c.
struct ast_threadstorage ts_temp_pvt = { .once = PTHREAD_ONCE_INIT , .key_init = temp_pvt_init , } [static] |
struct ast_user_list userl [static] |
The user list: Users and friends.