#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, INFO" |
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_RPORT_PRESENT (1 << 30) |
#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_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_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 | media_type { SDP_AUDIO, SDP_VIDEO } |
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_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 int | __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, int add_audio, int add_t38) |
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_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, struct sockaddr_in *sin) |
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_ip_and_port_from_sdp (struct sip_request *req, const enum media_type media, struct sockaddr_in *sin) |
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 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 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, int lastms) |
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 | resp_needs_contact (const char *msg, enum sipmethod method) |
Test if this response needs a contact header. | |
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_nonce_randdata (struct sip_pvt *p, int forceupdate) |
builds the sip_pvt's randdata field which is used for the nonce challenge. When forceupdate is not set, the nonce is only updated if the current one is stale. In this case, a stalenonce is one which has already received a response, if a nonce has not received a response it is not always necessary or beneficial to create a new one. | |
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, int force) |
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 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, int sipmethod, struct sip_request *req, enum xmittype 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 = "6989f2ec67f8497e38c12890500c525b" , .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 = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, 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 = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } |
static ast_mutex_t | netlock = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, 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 | seen_lastms = 0 |
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 = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, 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 | 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. |
SIP over TLS
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, INFO" |
SIP Methods we support.
Definition at line 477 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 1874 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_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), 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 370 of file chan_sip.c.
#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
Definition at line 371 of file chan_sip.c.
#define CAN_NOT_CREATE_DIALOG 0 |
Definition at line 369 of file chan_sip.c.
#define CHECK_AUTH_BUF_INITLEN 256 |
Definition at line 8755 of file chan_sip.c.
Referenced by check_auth(), and transmit_fake_auth_response().
#define DEC_CALL_LIMIT 0 |
Definition at line 614 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 616 of file chan_sip.c.
Referenced by handle_response_invite(), and update_call_counter().
#define DEFAULT_ALLOW_EXT_DOM TRUE |
Definition at line 509 of file chan_sip.c.
#define DEFAULT_ALLOWGUEST TRUE |
Definition at line 503 of file chan_sip.c.
#define DEFAULT_AUTOCREATEPEER FALSE |
Definition at line 513 of file chan_sip.c.
#define DEFAULT_CALLERID "asterisk" |
Definition at line 500 of file chan_sip.c.
#define DEFAULT_COMPACTHEADERS FALSE |
Definition at line 505 of file chan_sip.c.
#define DEFAULT_CONTEXT "default" |
Definition at line 496 of file chan_sip.c.
#define DEFAULT_DEFAULT_EXPIRY 120 |
Definition at line 172 of file chan_sip.c.
#define DEFAULT_EXPIRY 900 |
Expire slowly
Definition at line 189 of file chan_sip.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Qualification: How often to check, if the host is down...
Definition at line 205 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 204 of file chan_sip.c.
#define DEFAULT_MAX_CALL_BITRATE (384) |
Max bitrate for video
Definition at line 516 of file chan_sip.c.
#define DEFAULT_MAX_EXPIRY 3600 |
Definition at line 174 of file chan_sip.c.
#define DEFAULT_MAX_FORWARDS "70" |
Definition at line 176 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 203 of file chan_sip.c.
#define DEFAULT_MIN_EXPIRY 60 |
Definition at line 173 of file chan_sip.c.
#define DEFAULT_MOHINTERPRET "default" |
Definition at line 497 of file chan_sip.c.
#define DEFAULT_MOHSUGGEST "" |
Definition at line 498 of file chan_sip.c.
#define DEFAULT_MWITIME 10 |
Definition at line 502 of file chan_sip.c.
#define DEFAULT_NOTIFYMIME "application/simple-message-summary" |
Definition at line 501 of file chan_sip.c.
#define DEFAULT_NOTIFYRINGING TRUE |
Definition at line 511 of file chan_sip.c.
#define DEFAULT_PEDANTIC FALSE |
Definition at line 512 of file chan_sip.c.
#define DEFAULT_QUALIFY FALSE |
Definition at line 514 of file chan_sip.c.
#define DEFAULT_REALM "asterisk" |
Definition at line 510 of file chan_sip.c.
#define DEFAULT_REGISTRATION_TIMEOUT 20 |
Definition at line 175 of file chan_sip.c.
#define DEFAULT_RETRANS 1000 |
How frequently to retransmit Default: 2 * 500 ms in RFC 3261
Definition at line 207 of file chan_sip.c.
#define DEFAULT_SRVLOOKUP TRUE |
Recommended setting is ON
Definition at line 504 of file chan_sip.c.
#define DEFAULT_T1MIN 100 |
100 MS for minimal roundtrip time
Definition at line 515 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 507 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 506 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 508 of file chan_sip.c.
#define DEFAULT_TRANS_TIMEOUT -1 |
Definition at line 212 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(), sip_send_mwi_to_peer(), and transmit_fake_auth_response().
#define DEFAULT_USERAGENT "Asterisk PBX" |
Default Useragent: header unless re-defined in sip.conf
Definition at line 518 of file chan_sip.c.
#define DEFAULT_VMEXTEN "asterisk" |
Definition at line 499 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 181 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 183 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 187 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 180 of file chan_sip.c.
Referenced by handle_response_register().
#define FALSE 0 |
Definition at line 154 of file chan_sip.c.
#define FLAG_FATAL (1 << 1) |
#define FLAG_RESPONSE (1 << 0) |
Definition at line 1041 of file chan_sip.c.
Referenced by __sip_ack(), __sip_pretend_ack(), __sip_reliable_xmit(), __sip_semi_ack(), handle_request(), handle_request_invite(), retrans_pkt(), and sip_hangup().
#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 615 of file chan_sip.c.
Referenced by handle_request_invite(), and update_call_counter().
#define INC_CALL_RINGING 3 |
#define INITIAL_CSEQ 101 |
our initial sip sequence number
Definition at line 221 of file chan_sip.c.
Referenced by sip_alloc(), sip_register(), and transmit_response_using_temp().
#define IPTOS_MINCOST 0x02 |
Definition at line 167 of file chan_sip.c.
#define MAX | ( | a, | |||
b | ) | ((a) > (b) ? (a) : (b)) |
Definition at line 198 of file chan_sip.c.
#define MAX_AUTHTRIES 3 |
Try authentication three times, then fail
Definition at line 213 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 1039 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 208 of file chan_sip.c.
#define NO_RTP 0 |
Definition at line 237 of file chan_sip.c.
#define NOT_SUPPORTED 0 |
Definition at line 410 of file chan_sip.c.
#define RTP 1 |
Definition at line 236 of file chan_sip.c.
#define SDP_MAX_RTPMAP_CODECS 32 |
Maximum number of codecs allowed in received SDP
Definition at line 219 of file chan_sip.c.
Referenced by process_sdp().
#define SDP_SAMPLE_RATE | ( | x | ) | 8000 |
Definition at line 6670 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 722 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 763 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 751 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 752 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 737 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 738 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 742 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), process_sdp(), sip_alloc(), and sip_new().
#define SIP_DTMF_INBAND (1 << 16) |
DTMF Support: Inband audio, only for ULAW/ALAW - "inband"
Definition at line 740 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 741 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 739 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 768 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 736 of file chan_sip.c.
#define SIP_G726_NONSTANDARD (1 << 31) |
Use non-standard packing for G726-32 data
Definition at line 766 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 729 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 765 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 756 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 755 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 215 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 216 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 217 of file chan_sip.c.
#define SIP_NAT (3 << 18) |
four settings, uses two bits
Definition at line 744 of file chan_sip.c.
Referenced by _sip_show_peer(), build_via(), copy_via_headers(), create_addr(), 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 748 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 745 of file chan_sip.c.
Referenced by handle_common_options(), and nat2str().
#define SIP_NAT_RFC3581 (1 << 18) |
NAT RFC3581
Definition at line 746 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 747 of file chan_sip.c.
Referenced by _sip_show_peers(), build_peer(), check_user_full(), create_addr(), 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 723 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 727 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 762 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 724 of file chan_sip.c.
Referenced by add_sdp(), process_sdp(), and sip_indicate().
#define SIP_OPT_100REL (1 << 1) |
Definition at line 413 of file chan_sip.c.
#define SIP_OPT_EARLY_SESSION (1 << 3) |
Definition at line 415 of file chan_sip.c.
#define SIP_OPT_EVENTLIST (1 << 11) |
Definition at line 423 of file chan_sip.c.
#define SIP_OPT_GRUU (1 << 12) |
Definition at line 424 of file chan_sip.c.
#define SIP_OPT_HISTINFO (1 << 15) |
Definition at line 427 of file chan_sip.c.
#define SIP_OPT_JOIN (1 << 4) |
Definition at line 416 of file chan_sip.c.
#define SIP_OPT_NOREFERSUB (1 << 14) |
Definition at line 426 of file chan_sip.c.
#define SIP_OPT_PATH (1 << 5) |
Definition at line 417 of file chan_sip.c.
#define SIP_OPT_PRECONDITION (1 << 7) |
Definition at line 419 of file chan_sip.c.
#define SIP_OPT_PREF (1 << 6) |
Definition at line 418 of file chan_sip.c.
#define SIP_OPT_PRIVACY (1 << 8) |
Definition at line 420 of file chan_sip.c.
#define SIP_OPT_REPLACES (1 << 0) |
#define SIP_OPT_RESPRIORITY (1 << 16) |
Definition at line 428 of file chan_sip.c.
#define SIP_OPT_SDP_ANAT (1 << 9) |
Definition at line 421 of file chan_sip.c.
#define SIP_OPT_SEC_AGREE (1 << 10) |
Definition at line 422 of file chan_sip.c.
#define SIP_OPT_TARGET_DIALOG (1 << 13) |
Definition at line 425 of file chan_sip.c.
#define SIP_OPT_TIMER (1 << 2) |
Definition at line 414 of file chan_sip.c.
#define SIP_OUTGOING (1 << 13) |
Direction of the last transaction in this dialog
Definition at line 735 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 790 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 789 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 802 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 797 of file chan_sip.c.
Referenced by __sip_destroy(), __sip_show_channels(), add_sdp(), change_hold_state(), do_monitor(), 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 800 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 799 of file chan_sip.c.
Referenced by add_sdp(), and change_hold_state().
#define SIP_PAGE2_DEBUG (3 << 11) |
Definition at line 783 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
Definition at line 784 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
Definition at line 785 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 805 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 786 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 782 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 792 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 803 of file chan_sip.c.
Referenced by get_sip_pvt_byid_locked(), handle_response_invite(), sip_request_call(), and update_call_counter().
#define SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) |
25: ????
Definition at line 801 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_RPORT_PRESENT (1 << 30) |
30: Was rport received in the Via header?
Definition at line 806 of file chan_sip.c.
Referenced by check_user_full(), and check_via().
#define SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
Definition at line 778 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 775 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 779 of file chan_sip.c.
Referenced by realtime_update_peer(), and sip_show_settings().
#define SIP_PAGE2_RTUPDATE (1 << 1) |
Definition at line 776 of file chan_sip.c.
Referenced by destroy_association(), handle_response_peerpoke(), sip_poke_noanswer(), sip_show_settings(), and update_peer().
#define SIP_PAGE2_SELFDESTRUCT (1 << 14) |
Automatic peers need to destruct themselves
Definition at line 787 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 781 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 791 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 793 of file chan_sip.c.
Referenced by create_addr_from_peer(), sip_alloc(), and sip_write().
#define SIP_PAGE2_T38SUPPORT_RTP (2 << 20) |
21: T38 Fax Passthrough Support (not implemented)
Definition at line 795 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 796 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 794 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_UDPTL_DESTINATION (1 << 28) |
28: Use source IP of RTP as destination if NAT is enabled
Definition at line 804 of file chan_sip.c.
Referenced by handle_common_options(), and process_sdp().
#define SIP_PAGE2_VIDEOSUPPORT (1 << 15) |
Definition at line 788 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 728 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(), register_verify(), and transmit_fake_auth_response().
#define SIP_PKT_IGNORE_REQ (1 << 4) |
#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 758 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 760 of file chan_sip.c.
Referenced by handle_common_options(), and sip_show_settings().
#define SIP_PROG_INBAND_YES (2 << 25) |
Definition at line 761 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 726 of file chan_sip.c.
Referenced by sip_indicate(), and sip_write().
#define SIP_PROMISCREDIR (1 << 8) |
Promiscuous redirection
Definition at line 730 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 733 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 753 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 764 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 209 of file chan_sip.c.
Referenced by sip_call(), and sip_sipredirect().
#define SIP_TRUSTRPID (1 << 9) |
Trust RPID headers?
Definition at line 731 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 734 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 732 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), initreqprep(), and sip_show_settings().
#define SIPBUFSIZE 512 |
Definition at line 161 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 844 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 845 of file chan_sip.c.
#define sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
Definition at line 846 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 483 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(), transmit_notify_with_mwi(), 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 409 of file chan_sip.c.
#define SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support.
Definition at line 480 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 819 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp().
#define T38FAX_RATE_12000 (1 << 12) |
12000 bps t38FaxRate
Definition at line 838 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 839 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 834 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 835 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 836 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 837 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 824 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp().
#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
Definition at line 823 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 821 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp().
#define T38FAX_TRANSCODING_MMR (1 << 1) |
Default: 0 (unset)
Definition at line 820 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp().
#define T38FAX_UDP_EC_FEC (1 << 4) |
Set for t38UDPFEC
Definition at line 827 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 826 of file chan_sip.c.
Referenced by add_sdp(), create_addr_from_peer(), process_sdp(), and sip_alloc().
#define T38FAX_UDP_EC_REDUNDANCY (2 << 4) |
Set for t38UDPRedundancy
Definition at line 828 of file chan_sip.c.
Referenced by add_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 830 of file chan_sip.c.
Referenced by add_sdp().
#define T38FAX_VERSION_0 (0 << 6) |
#define T38FAX_VERSION_1 (1 << 6) |
#define TRUE 1 |
Definition at line 158 of file chan_sip.c.
#define UNLINK | ( | element, | |||
head, | |||||
prev | ) |
--- some list management macros.
Definition at line 1627 of file chan_sip.c.
Referenced by __sip_ack(), __sip_destroy(), and handle_request_cancel().
#define VIDEO_CODEC_MASK 0x1fc0000 |
Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO
Definition at line 165 of file chan_sip.c.
#define XMIT_ERROR -2 |
Definition at line 163 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 345 of file chan_sip.c.
00345 { 00346 AUTH_SUCCESSFUL = 0, 00347 AUTH_CHALLENGE_SENT = 1, 00348 AUTH_SECRET_FAILED = -1, 00349 AUTH_USERNAME_MISMATCH = -2, 00350 AUTH_NOT_FOUND = -3, 00351 AUTH_FAKE_AUTH = -4, 00352 AUTH_UNKNOWN_DOMAIN = -5, 00353 AUTH_PEER_NOT_DYNAMIC = -6, 00354 AUTH_ACL_FAILED = -7, 00355 };
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 685 of file chan_sip.c.
00685 { 00686 SIP_DOMAIN_AUTO, /*!< This domain is auto-configured */ 00687 SIP_DOMAIN_CONFIG, /*!< This domain is from configuration */ 00688 };
enum invitestates |
States for the INVITE transaction, not the dialog.
Definition at line 256 of file chan_sip.c.
00256 { 00257 INV_NONE = 0, /*!< No state at all, maybe not an INVITE dialog */ 00258 INV_CALLING = 1, /*!< Invite sent, no answer */ 00259 INV_PROCEEDING = 2, /*!< We got/sent 1xx message */ 00260 INV_EARLY_MEDIA = 3, /*!< We got/sent 18x message with to-tag back */ 00261 INV_COMPLETED = 4, /*!< Got final response with error. Wait for ACK, then CONFIRMED */ 00262 INV_CONFIRMED = 5, /*!< Confirmed response - we've got an ack (Incoming calls only) */ 00263 INV_TERMINATED = 6, /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done 00264 The only way out of this is a BYE from one side */ 00265 INV_CANCELLED = 7, /*!< Transaction cancelled by client or server in non-terminated state */ 00266 };
enum media_type |
Definition at line 283 of file chan_sip.c.
00283 { 00284 PARSE_REGISTER_FAILED, 00285 PARSE_REGISTER_UPDATE, 00286 PARSE_REGISTER_QUERY, 00287 };
enum referstatus |
Parameters to know status of transfer.
Definition at line 868 of file chan_sip.c.
00868 { 00869 REFER_IDLE, /*!< No REFER is in progress */ 00870 REFER_SENT, /*!< Sent REFER to transferee */ 00871 REFER_RECEIVED, /*!< Received REFER from transferer */ 00872 REFER_CONFIRMED, /*!< Refer confirmed with a 100 TRYING */ 00873 REFER_ACCEPTED, /*!< Accepted by transferee */ 00874 REFER_RINGING, /*!< Target Ringing */ 00875 REFER_200OK, /*!< Answered by transfer target */ 00876 REFER_FAILED, /*!< REFER declined - go on */ 00877 REFER_NOAUTH /*!< We had no auth for REFER */ 00878 };
enum sip_auth_type |
Authentication types - proxy or www authentication.
Definition at line 339 of file chan_sip.c.
00339 { 00340 PROXY_AUTH, 00341 WWW_AUTH, 00342 };
enum sip_result |
Definition at line 248 of file chan_sip.c.
00248 { 00249 AST_SUCCESS = 0, 00250 AST_FAILURE = -1, 00251 };
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 314 of file chan_sip.c.
00314 { 00315 SIP_UNKNOWN, /* Unknown response */ 00316 SIP_RESPONSE, /* Not request, response to outbound request */ 00317 SIP_REGISTER, 00318 SIP_OPTIONS, 00319 SIP_NOTIFY, 00320 SIP_INVITE, 00321 SIP_ACK, 00322 SIP_PRACK, /* Not supported at all */ 00323 SIP_BYE, 00324 SIP_REFER, 00325 SIP_SUBSCRIBE, 00326 SIP_MESSAGE, 00327 SIP_UPDATE, /* We can send UPDATE; but not accept it */ 00328 SIP_INFO, 00329 SIP_CANCEL, 00330 SIP_PUBLISH, /* Not supported at all */ 00331 SIP_PING, /* Not supported at all, no standard but still implemented out there */ 00332 };
enum sipregistrystate |
States for outbound registrations (with register= lines in sip.conf.
Definition at line 358 of file chan_sip.c.
00358 { 00359 REG_STATE_UNREGISTERED = 0, /*!< We are not registered */ 00360 REG_STATE_REGSENT, /*!< Registration request sent */ 00361 REG_STATE_AUTHSENT, /*!< We have tried to authenticate */ 00362 REG_STATE_REGISTERED, /*!< Registered and done */ 00363 REG_STATE_REJECTED, /*!< Registration rejected */ 00364 REG_STATE_TIMEOUT, /*!< Registration timed out */ 00365 REG_STATE_NOAUTH, /*!< We have no accepted credentials */ 00366 REG_STATE_FAILED, /*!< Registration failed after several tries */ 00367 };
enum subscriptiontype |
Definition at line 289 of file chan_sip.c.
00289 { 00290 NONE = 0, 00291 XPIDF_XML, 00292 DIALOG_INFO_XML, 00293 CPIM_PIDF_XML, 00294 PIDF_XML, 00295 MWI_NOTIFICATION 00296 };
enum t38state |
T38 States for a call.
T38_DISABLED | Not enabled |
T38_LOCAL_REINVITE | Offered from local - REINVITE |
T38_PEER_DIRECT | Offered from peer |
T38_PEER_REINVITE | Offered from peer - REINVITE |
T38_ENABLED | Negotiated (enabled) |
Definition at line 849 of file chan_sip.c.
00849 { 00850 T38_DISABLED = 0, /*!< Not enabled */ 00851 T38_LOCAL_REINVITE, /*!< Offered from local - REINVITE */ 00852 T38_PEER_DIRECT, /*!< Offered from peer */ 00853 T38_PEER_REINVITE, /*!< Offered from peer - REINVITE */ 00854 T38_ENABLED /*!< Negotiated (enabled) */ 00855 };
enum transfermodes |
Authorization scheme for call transfers.
Definition at line 242 of file chan_sip.c.
00242 { 00243 TRANSFER_OPENFORALL, /*!< Allow all SIP transfers */ 00244 TRANSFER_CLOSED, /*!< Allow no SIP transfers */ 00245 };
enum xmittype |
Definition at line 276 of file chan_sip.c.
00276 { 00277 XMIT_CRITICAL = 2, /*!< Transmit critical SIP message reliably, with re-transmits. 00278 If it fails, it's critical and will cause a teardown of the session */ 00279 XMIT_RELIABLE = 1, /*!< Transmit SIP message reliably, with re-transmits */ 00280 XMIT_UNRELIABLE = 0, /*!< Transmit SIP message without bothering with re-transmits */ 00281 };
static const char * __get_header | ( | const struct sip_request * | req, | |
const char * | name, | |||
int * | start | |||
) | [static] |
Definition at line 4397 of file chan_sip.c.
References ast_skip_blanks(), find_alias(), sip_request::header, sip_request::headers, and len().
04398 { 04399 int pass; 04400 04401 /* 04402 * Technically you can place arbitrary whitespace both before and after the ':' in 04403 * a header, although RFC3261 clearly says you shouldn't before, and place just 04404 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 04405 * a good idea to say you can do it, and if you can do it, why in the hell would. 04406 * you say you shouldn't. 04407 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 04408 * and we always allow spaces after that for compatibility. 04409 */ 04410 for (pass = 0; name && pass < 2;pass++) { 04411 int x, len = strlen(name); 04412 for (x=*start; x<req->headers; x++) { 04413 if (!strncasecmp(req->header[x], name, len)) { 04414 char *r = req->header[x] + len; /* skip name */ 04415 if (pedanticsipchecking) 04416 r = ast_skip_blanks(r); 04417 04418 if (*r == ':') { 04419 *start = x+1; 04420 return ast_skip_blanks(r+1); 04421 } 04422 } 04423 } 04424 if (pass == 0) /* Try aliases */ 04425 name = find_alias(name, NULL); 04426 } 04427 04428 /* Don't return NULL, so get_header is always a valid pointer */ 04429 return ""; 04430 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 19347 of file chan_sip.c.
static int __set_address_from_contact | ( | const char * | fullcontact, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 8373 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().
08374 { 08375 struct hostent *hp; 08376 struct ast_hostent ahp; 08377 int port; 08378 char *c, *host, *pt; 08379 char contact_buf[256]; 08380 char *contact; 08381 08382 /* Work on a copy */ 08383 ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf)); 08384 contact = contact_buf; 08385 08386 /* Make sure it's a SIP URL */ 08387 if (strncasecmp(contact, "sip:", 4)) { 08388 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 08389 } else 08390 contact += 4; 08391 08392 /* Ditch arguments */ 08393 /* XXX this code is replicated also shortly below */ 08394 08395 /* Grab host */ 08396 host = strchr(contact, '@'); 08397 if (!host) { /* No username part */ 08398 host = contact; 08399 c = NULL; 08400 } else { 08401 *host++ = '\0'; 08402 } 08403 pt = strchr(host, ':'); 08404 if (pt) { 08405 *pt++ = '\0'; 08406 port = atoi(pt); 08407 } else 08408 port = STANDARD_SIP_PORT; 08409 08410 contact = strsep(&contact, ";"); /* trim ; and beyond in username part */ 08411 host = strsep(&host, ";"); /* trim ; and beyond in host/domain part */ 08412 08413 /* XXX This could block for a long time XXX */ 08414 /* We should only do this if it's a name, not an IP */ 08415 hp = ast_gethostbyname(host, &ahp); 08416 if (!hp) { 08417 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 08418 return -1; 08419 } 08420 sin->sin_family = AF_INET; 08421 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 08422 sin->sin_port = htons(port); 08423 08424 return 0; 08425 }
static int __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 2190 of file chan_sip.c.
References ast_log(), AST_SCHED_DEL_SPINLOCK, ast_test_flag, sip_pvt::callid, sip_pkt::data, FALSE, FLAG_RESPONSE, free, sip_pvt::lock, LOG_DEBUG, sip_pkt::next, option_debug, sip_pvt::packets, sip_pvt::pendinginvite, sip_pkt::retransid, sched, sip_pkt::seqno, sip_methods, sipdebug, cfsip_methods::text, TRUE, and UNLINK.
Referenced by __sip_pretend_ack(), handle_request(), handle_request_invite(), and handle_response().
02191 { 02192 struct sip_pkt *cur, *prev = NULL; 02193 02194 /* Just in case... */ 02195 char *msg; 02196 int res = FALSE; 02197 02198 msg = sip_methods[sipmethod].text; 02199 02200 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 02201 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 02202 ((ast_test_flag(cur, FLAG_RESPONSE)) || 02203 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 02204 if (!resp && (seqno == p->pendinginvite)) { 02205 if (option_debug) 02206 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 02207 p->pendinginvite = 0; 02208 } 02209 /* this is our baby */ 02210 res = TRUE; 02211 UNLINK(cur, p->packets, prev); 02212 if (cur->retransid > -1) { 02213 if (sipdebug && option_debug > 3) 02214 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 02215 } 02216 /* This odd section is designed to thwart a 02217 * race condition in the packet scheduler. There are 02218 * two conditions under which deleting the packet from the 02219 * scheduler can fail. 02220 * 02221 * 1. The packet has been removed from the scheduler because retransmission 02222 * is being attempted. The problem is that if the packet is currently attempting 02223 * retransmission and we are at this point in the code, then that MUST mean 02224 * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the 02225 * lock temporarily to allow retransmission. 02226 * 02227 * 2. The packet has reached its maximum number of retransmissions and has 02228 * been permanently removed from the packet scheduler. If this is the case, then 02229 * the packet's retransid will be set to -1. The atomicity of the setting and checking 02230 * of the retransid to -1 is ensured since in both cases p's lock is held. 02231 */ 02232 AST_SCHED_DEL_SPINLOCK(sched, cur->retransid, &p->lock); 02233 free(cur); 02234 break; 02235 } 02236 } 02237 if (option_debug) 02238 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"); 02239 return res; 02240 }
static int __sip_autodestruct | ( | const void * | data | ) | [static] |
Kill a SIP dialog (called by scheduler).
Definition at line 2103 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, sip_pvt::lastmsg, LOG_DEBUG, LOG_WARNING, sip_pvt::method, method_match(), 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().
02104 { 02105 struct sip_pvt *p = (struct sip_pvt *)data; 02106 02107 /* If this is a subscription, tell the phone that we got a timeout */ 02108 if (p->subscribed) { 02109 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 02110 p->subscribed = NONE; 02111 append_history(p, "Subscribestatus", "timeout"); 02112 if (option_debug > 2) 02113 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>"); 02114 return 10000; /* Reschedule this destruction so that we know that it's gone */ 02115 } 02116 02117 /* If there are packets still waiting for delivery, delay the destruction */ 02118 /* via bug 12101, the two usages of SIP_NEEDDESTROY in the following block 02119 * of code make a sort of "safety relief valve", that allows sip channels 02120 * that were created via INVITE, then thru some sequence were CANCELED, 02121 * to die, rather than infinitely be rescheduled */ 02122 if (p->packets && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 02123 char method_str[30]; 02124 if (option_debug > 2) 02125 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>"); 02126 append_history(p, "ReliableXmit", "timeout"); 02127 if (sscanf(p->lastmsg, "Tx: %30s", method_str) == 1 || sscanf(p->lastmsg, "Rx: %30s", method_str) == 1) { 02128 if (method_match(SIP_CANCEL, method_str) || method_match(SIP_BYE, method_str)) { 02129 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 02130 } 02131 } 02132 return 10000; 02133 } 02134 02135 /* If we're destroying a subscription, dereference peer object too */ 02136 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 02137 ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer); 02138 02139 /* Reset schedule ID */ 02140 p->autokillid = -1; 02141 02142 if (option_debug) 02143 ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid); 02144 append_history(p, "AutoDestroy", "%s", p->callid); 02145 if (p->owner) { 02146 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 02147 ast_queue_hangup(p->owner); 02148 } else if (p->refer && !ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 02149 if (option_debug > 2) 02150 ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid); 02151 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 02152 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 02153 } else 02154 sip_destroy(p); 02155 return 0; 02156 }
static int __sip_destroy | ( | struct sip_pvt * | p, | |
int | lockowner | |||
) | [static] |
Execute destruction of SIP dialog structure, release memory.
Definition at line 3150 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().
03151 { 03152 struct sip_pvt *cur, *prev = NULL; 03153 struct sip_pkt *cp; 03154 struct sip_request *req; 03155 03156 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 03157 if (p->rtp && ast_rtp_get_bridged(p->rtp)) { 03158 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03159 return -1; 03160 } 03161 03162 if (p->vrtp && ast_rtp_get_bridged(p->vrtp)) { 03163 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03164 return -1; 03165 } 03166 03167 if (sip_debug_test_pvt(p) || option_debug > 2) 03168 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03169 03170 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03171 update_call_counter(p, DEC_CALL_LIMIT); 03172 if (option_debug > 1) 03173 ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 03174 } 03175 03176 /* Unlink us from the owner if we have one */ 03177 if (p->owner) { 03178 if (lockowner) 03179 ast_channel_lock(p->owner); 03180 if (option_debug) 03181 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 03182 p->owner->tech_pvt = NULL; 03183 /* Make sure that the channel knows its backend is going away */ 03184 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03185 if (lockowner) 03186 ast_channel_unlock(p->owner); 03187 /* Give the channel a chance to react before deallocation */ 03188 usleep(1); 03189 } 03190 03191 /* Remove link from peer to subscription of MWI */ 03192 if (p->relatedpeer) { 03193 if (p->relatedpeer->mwipvt == p) { 03194 p->relatedpeer->mwipvt = NULL; 03195 } 03196 ASTOBJ_UNREF(p->relatedpeer, sip_destroy_peer); 03197 } 03198 03199 if (dumphistory) 03200 sip_dump_history(p); 03201 03202 if (p->options) 03203 free(p->options); 03204 03205 if (p->stateid > -1) 03206 ast_extension_state_del(p->stateid, NULL); 03207 AST_SCHED_DEL(sched, p->initid); 03208 AST_SCHED_DEL(sched, p->waitid); 03209 AST_SCHED_DEL(sched, p->autokillid); 03210 AST_SCHED_DEL(sched, p->request_queue_sched_id); 03211 03212 if (p->rtp) { 03213 ast_rtp_destroy(p->rtp); 03214 } 03215 if (p->vrtp) { 03216 ast_rtp_destroy(p->vrtp); 03217 } 03218 if (p->udptl) 03219 ast_udptl_destroy(p->udptl); 03220 if (p->refer) 03221 free(p->refer); 03222 if (p->route) { 03223 free_old_route(p->route); 03224 p->route = NULL; 03225 } 03226 if (p->registry) { 03227 if (p->registry->call == p) 03228 p->registry->call = NULL; 03229 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 03230 } 03231 03232 /* Clear history */ 03233 if (p->history) { 03234 struct sip_history *hist; 03235 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 03236 free(hist); 03237 p->history_entries--; 03238 } 03239 free(p->history); 03240 p->history = NULL; 03241 } 03242 03243 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 03244 ast_free(req); 03245 } 03246 03247 for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) { 03248 if (cur == p) { 03249 UNLINK(cur, iflist, prev); 03250 break; 03251 } 03252 } 03253 if (!cur) { 03254 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 03255 return 0; 03256 } 03257 03258 /* remove all current packets in this dialog */ 03259 while((cp = p->packets)) { 03260 p->packets = p->packets->next; 03261 AST_SCHED_DEL(sched, cp->retransid); 03262 free(cp); 03263 } 03264 if (p->chanvars) { 03265 ast_variables_destroy(p->chanvars); 03266 p->chanvars = NULL; 03267 } 03268 ast_mutex_destroy(&p->lock); 03269 03270 ast_string_field_free_memory(p); 03271 03272 free(p); 03273 return 0; 03274 }
static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 7799 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
07800 { 07801 int res; 07802 07803 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 07804 return res; 07805 }
static void __sip_pretend_ack | ( | struct sip_pvt * | p | ) | [static] |
Pretend to ack all packets called with p locked.
Definition at line 2244 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(), and sip_reg_timeout().
02245 { 02246 struct sip_pkt *cur = NULL; 02247 02248 while (p->packets) { 02249 int method; 02250 if (cur == p->packets) { 02251 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 02252 return; 02253 } 02254 cur = p->packets; 02255 method = (cur->method) ? cur->method : find_sip_method(cur->data); 02256 __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method); 02257 } 02258 }
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 2050 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().
02051 { 02052 struct sip_pkt *pkt; 02053 int siptimer_a = DEFAULT_RETRANS; 02054 int xmitres = 0; 02055 int respid; 02056 02057 if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) 02058 return AST_FAILURE; 02059 memcpy(pkt->data, data, len); 02060 pkt->method = sipmethod; 02061 pkt->packetlen = len; 02062 pkt->next = p->packets; 02063 pkt->owner = p; 02064 pkt->seqno = seqno; 02065 pkt->data[len] = '\0'; 02066 if (resp) { 02067 ast_set_flag(pkt, FLAG_RESPONSE); 02068 /* Parse out the response code */ 02069 if (sscanf(pkt->data, "SIP/2.0 %30d", &respid) == 1) { 02070 pkt->response_code = respid; 02071 } 02072 } 02073 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 02074 pkt->retransid = -1; 02075 if (fatal) 02076 ast_set_flag(pkt, FLAG_FATAL); 02077 if (pkt->timer_t1) 02078 siptimer_a = pkt->timer_t1 * 2; 02079 02080 if (option_debug > 3 && sipdebug) 02081 ast_log(LOG_DEBUG, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid); 02082 pkt->retransid = -1; 02083 pkt->next = p->packets; 02084 p->packets = pkt; 02085 if (sipmethod == SIP_INVITE) { 02086 /* Note this is a pending invite */ 02087 p->pendinginvite = seqno; 02088 } 02089 02090 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 02091 02092 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 02093 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02094 return AST_FAILURE; 02095 } else { 02096 /* Schedule retransmission */ 02097 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 02098 return AST_SUCCESS; 02099 } 02100 }
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 2261 of file chan_sip.c.
References ast_log(), AST_SCHED_DEL, ast_test_flag, sip_pvt::callid, sip_pkt::data, FALSE, FLAG_RESPONSE, LOG_DEBUG, method_match(), sip_pkt::next, option_debug, sip_pvt::packets, sip_pkt::retransid, sched, sip_pkt::seqno, sip_methods, sipdebug, cfsip_methods::text, and TRUE.
Referenced by handle_response(), and sip_hangup().
02262 { 02263 struct sip_pkt *cur; 02264 int res = FALSE; 02265 02266 for (cur = p->packets; cur; cur = cur->next) { 02267 if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp && 02268 (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) { 02269 /* this is our baby */ 02270 if (cur->retransid > -1) { 02271 if (option_debug > 3 && sipdebug) 02272 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 02273 } 02274 AST_SCHED_DEL(sched, cur->retransid); 02275 res = TRUE; 02276 break; 02277 } 02278 } 02279 if (option_debug) 02280 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"); 02281 return res; 02282 }
static int __sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[], | |||
int | subscriptions | |||
) | [static] |
SIP show channels CLI (main function).
Definition at line 11327 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().
11328 { 11329 #define FORMAT3L "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" 11330 #define FORMAT3H "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" 11331 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" 11332 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" 11333 struct sip_pvt *cur; 11334 int numchans = 0; 11335 int usedchans = 0; 11336 char *referstatus = NULL; 11337 11338 if (argc != 3) 11339 return RESULT_SHOWUSAGE; 11340 ast_mutex_lock(&iflock); 11341 cur = iflist; 11342 if (!subscriptions) 11343 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 11344 else 11345 ast_cli(fd, FORMAT3H, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry"); 11346 for (; cur; cur = cur->next) { 11347 referstatus = ""; 11348 if (cur->refer) { /* SIP transfer in progress */ 11349 referstatus = referstatus2str(cur->refer->status); 11350 } 11351 if (cur->subscribed == NONE && !subscriptions) { 11352 char formatbuf[SIPBUFSIZE/2]; 11353 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 11354 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 11355 cur->callid, 11356 cur->ocseq, cur->icseq, 11357 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 11358 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 11359 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 11360 cur->lastmsg , 11361 referstatus 11362 ); 11363 numchans++; 11364 } 11365 if (cur->subscribed != NONE && subscriptions) { 11366 ast_cli(fd, FORMAT3L, ast_inet_ntoa(cur->sa.sin_addr), 11367 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 11368 cur->callid, 11369 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 11370 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 11371 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 11372 subscription_type2str(cur->subscribed), 11373 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>", 11374 cur->expiry 11375 ); 11376 numchans++; 11377 } 11378 if (cur->owner) { /* Count SIP dialog owned by a real channel */ 11379 usedchans++; 11380 } 11381 } 11382 ast_mutex_unlock(&iflock); 11383 if (!subscriptions) 11384 ast_cli(fd, "%d active SIP dialog%s\n", numchans, (numchans != 1) ? "s" : ""); 11385 else 11386 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 11387 ast_cli(fd, "%d used SIP channel%s\n", usedchans, (usedchans != 1) ? "s" : ""); 11388 return RESULT_SUCCESS; 11389 #undef FORMAT 11390 #undef FORMAT2 11391 #undef FORMAT3 11392 }
static int __sip_xmit | ( | struct sip_pvt * | p, | |
char * | data, | |||
int | len | |||
) | [static] |
Transmit SIP message.
Definition at line 1794 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_sched_add(), AST_SCHED_DEL, errno, LOG_WARNING, sip_registry::needdns, REG_STATE_REGISTERED, sip_pvt::registry, sip_registry::regstate, sched, sip_real_dst(), sip_reg_timeout(), sipsock, sip_registry::timeout, TRUE, and XMIT_ERROR.
Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response().
01795 { 01796 int res; 01797 const struct sockaddr_in *dst = sip_real_dst(p); 01798 res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)); 01799 01800 if (res == -1) { 01801 switch (errno) { 01802 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 01803 case EHOSTUNREACH: /* Host can't be reached */ 01804 case ENETDOWN: /* Inteface down */ 01805 case ENETUNREACH: /* Network failure */ 01806 case ECONNREFUSED: /* ICMP port unreachable */ 01807 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 01808 } 01809 01810 if (p->registry && p->registry->regstate < REG_STATE_REGISTERED) { 01811 AST_SCHED_DEL(sched, p->registry->timeout); 01812 p->registry->needdns = TRUE; 01813 p->registry->timeout = ast_sched_add(sched, 1, sip_reg_timeout, p->registry); 01814 } 01815 } 01816 01817 if (res != len) 01818 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)); 01819 return res; 01820 }
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 6361 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().
06362 { 06363 struct sip_request resp; 06364 int seqno = 0; 06365 06366 if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) { 06367 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06368 return -1; 06369 } 06370 respprep(&resp, p, msg, req); 06371 add_header_contentLength(&resp, 0); 06372 /* If we are cancelling an incoming invite for some reason, add information 06373 about the reason why we are doing this in clear text */ 06374 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 06375 char buf[10]; 06376 06377 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 06378 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 06379 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 06380 } 06381 return send_response(p, &resp, reliable, seqno); 06382 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 19347 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 10885 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_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().
10886 { 10887 char status[30] = ""; 10888 char cbuf[256]; 10889 struct sip_peer *peer; 10890 char codec_buf[512]; 10891 struct ast_codec_pref *pref; 10892 struct ast_variable *v; 10893 struct sip_auth *auth; 10894 int x = 0, codec = 0, load_realtime; 10895 int realtimepeers; 10896 10897 realtimepeers = ast_check_realtime("sippeers"); 10898 10899 if (argc < 4) 10900 return RESULT_SHOWUSAGE; 10901 10902 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10903 peer = find_peer(argv[3], NULL, load_realtime, 0); 10904 if (s) { /* Manager */ 10905 if (peer) { 10906 const char *id = astman_get_header(m,"ActionID"); 10907 10908 astman_append(s, "Response: Success\r\n"); 10909 if (!ast_strlen_zero(id)) 10910 astman_append(s, "ActionID: %s\r\n",id); 10911 } else { 10912 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]); 10913 astman_send_error(s, m, cbuf); 10914 return 0; 10915 } 10916 } 10917 if (peer && type==0 ) { /* Normal listing */ 10918 ast_cli(fd,"\n\n"); 10919 ast_cli(fd, " * Name : %s\n", peer->name); 10920 if (realtimepeers) { /* Realtime is enabled */ 10921 ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 10922 } 10923 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 10924 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 10925 for (auth = peer->auth; auth; auth = auth->next) { 10926 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 10927 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 10928 } 10929 ast_cli(fd, " Context : %s\n", peer->context); 10930 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 10931 ast_cli(fd, " Language : %s\n", peer->language); 10932 if (!ast_strlen_zero(peer->accountcode)) 10933 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 10934 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 10935 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 10936 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 10937 if (!ast_strlen_zero(peer->fromuser)) 10938 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 10939 if (!ast_strlen_zero(peer->fromdomain)) 10940 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 10941 ast_cli(fd, " Callgroup : "); 10942 print_group(fd, peer->callgroup, 0); 10943 ast_cli(fd, " Pickupgroup : "); 10944 print_group(fd, peer->pickupgroup, 0); 10945 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 10946 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 10947 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 10948 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 10949 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 10950 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 10951 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 10952 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 10953 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))); 10954 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10955 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 10956 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 10957 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10958 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 10959 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 10960 #endif 10961 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 10962 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 10963 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 10964 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 10965 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 10966 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 10967 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10968 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10969 10970 /* - is enumerated */ 10971 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10972 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 10973 ast_cli(fd, " ToHost : %s\n", peer->tohost); 10974 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)); 10975 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 10976 if (!ast_strlen_zero(global_regcontext)) 10977 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 10978 ast_cli(fd, " Def. Username: %s\n", peer->username); 10979 ast_cli(fd, " SIP Options : "); 10980 if (peer->sipoptions) { 10981 int lastoption = -1; 10982 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10983 if (sip_options[x].id != lastoption) { 10984 if (peer->sipoptions & sip_options[x].id) 10985 ast_cli(fd, "%s ", sip_options[x].text); 10986 lastoption = x; 10987 } 10988 } 10989 } else 10990 ast_cli(fd, "(none)"); 10991 10992 ast_cli(fd, "\n"); 10993 ast_cli(fd, " Codecs : "); 10994 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10995 ast_cli(fd, "%s\n", codec_buf); 10996 ast_cli(fd, " Codec Order : ("); 10997 print_codec_to_cli(fd, &peer->prefs); 10998 ast_cli(fd, ")\n"); 10999 11000 ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No"); 11001 ast_cli(fd, " Status : "); 11002 peer_status(peer, status, sizeof(status)); 11003 ast_cli(fd, "%s\n",status); 11004 ast_cli(fd, " Useragent : %s\n", peer->useragent); 11005 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 11006 if (peer->chanvars) { 11007 ast_cli(fd, " Variables :\n"); 11008 for (v = peer->chanvars ; v ; v = v->next) 11009 ast_cli(fd, " %s = %s\n", v->name, v->value); 11010 } 11011 ast_cli(fd,"\n"); 11012 ASTOBJ_UNREF(peer,sip_destroy_peer); 11013 } else if (peer && type == 1) { /* manager listing */ 11014 char buf[256]; 11015 astman_append(s, "Channeltype: SIP\r\n"); 11016 astman_append(s, "ObjectName: %s\r\n", peer->name); 11017 astman_append(s, "ChanObjectType: peer\r\n"); 11018 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 11019 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 11020 astman_append(s, "Context: %s\r\n", peer->context); 11021 astman_append(s, "Language: %s\r\n", peer->language); 11022 if (!ast_strlen_zero(peer->accountcode)) 11023 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 11024 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 11025 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 11026 if (!ast_strlen_zero(peer->fromuser)) 11027 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 11028 if (!ast_strlen_zero(peer->fromdomain)) 11029 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 11030 astman_append(s, "Callgroup: "); 11031 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup)); 11032 astman_append(s, "Pickupgroup: "); 11033 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup)); 11034 astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox); 11035 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 11036 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 11037 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 11038 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 11039 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 11040 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 11041 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 11042 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))); 11043 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 11044 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 11045 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 11046 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 11047 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 11048 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 11049 11050 /* - is enumerated */ 11051 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 11052 astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg); 11053 astman_append(s, "ToHost: %s\r\n", peer->tohost); 11054 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)); 11055 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)); 11056 astman_append(s, "Default-Username: %s\r\n", peer->username); 11057 if (!ast_strlen_zero(global_regcontext)) 11058 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 11059 astman_append(s, "Codecs: "); 11060 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 11061 astman_append(s, "%s\r\n", codec_buf); 11062 astman_append(s, "CodecOrder: "); 11063 pref = &peer->prefs; 11064 for(x = 0; x < 32 ; x++) { 11065 codec = ast_codec_pref_index(pref,x); 11066 if (!codec) 11067 break; 11068 astman_append(s, "%s", ast_getformatname(codec)); 11069 if (x < 31 && ast_codec_pref_index(pref,x+1)) 11070 astman_append(s, ","); 11071 } 11072 11073 astman_append(s, "\r\n"); 11074 astman_append(s, "Status: "); 11075 peer_status(peer, status, sizeof(status)); 11076 astman_append(s, "%s\r\n", status); 11077 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 11078 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 11079 if (peer->chanvars) { 11080 for (v = peer->chanvars ; v ; v = v->next) { 11081 astman_append(s, "ChanVariable:\n"); 11082 astman_append(s, " %s,%s\r\n", v->name, v->value); 11083 } 11084 } 11085 11086 ASTOBJ_UNREF(peer,sip_destroy_peer); 11087 11088 } else { 11089 ast_cli(fd,"Peer %s not found.\n", argv[3]); 11090 ast_cli(fd,"\n"); 11091 } 11092 11093 return RESULT_SUCCESS; 11094 }
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 10435 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().
10436 { 10437 regex_t regexbuf; 10438 int havepattern = FALSE; 10439 10440 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 10441 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 10442 10443 char name[256]; 10444 int total_peers = 0; 10445 int peers_mon_online = 0; 10446 int peers_mon_offline = 0; 10447 int peers_unmon_offline = 0; 10448 int peers_unmon_online = 0; 10449 const char *id; 10450 char idtext[256] = ""; 10451 int realtimepeers; 10452 10453 realtimepeers = ast_check_realtime("sippeers"); 10454 10455 if (s) { /* Manager - get ActionID */ 10456 id = astman_get_header(m,"ActionID"); 10457 if (!ast_strlen_zero(id)) 10458 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 10459 } 10460 10461 switch (argc) { 10462 case 5: 10463 if (!strcasecmp(argv[3], "like")) { 10464 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 10465 return RESULT_SHOWUSAGE; 10466 havepattern = TRUE; 10467 } else 10468 return RESULT_SHOWUSAGE; 10469 case 3: 10470 break; 10471 default: 10472 return RESULT_SHOWUSAGE; 10473 } 10474 10475 if (!s) /* Normal list */ 10476 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 10477 10478 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10479 char status[20] = ""; 10480 char srch[2000]; 10481 char pstatus; 10482 10483 ASTOBJ_RDLOCK(iterator); 10484 10485 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10486 ASTOBJ_UNLOCK(iterator); 10487 continue; 10488 } 10489 10490 if (!ast_strlen_zero(iterator->username) && !s) 10491 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 10492 else 10493 ast_copy_string(name, iterator->name, sizeof(name)); 10494 10495 pstatus = peer_status(iterator, status, sizeof(status)); 10496 if (pstatus == 1) 10497 peers_mon_online++; 10498 else if (pstatus == 0) 10499 peers_mon_offline++; 10500 else { 10501 if (iterator->addr.sin_port == 0) 10502 peers_unmon_offline++; 10503 else 10504 peers_unmon_online++; 10505 } 10506 10507 snprintf(srch, sizeof(srch), FORMAT, name, 10508 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10509 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10510 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10511 iterator->ha ? " A " : " ", /* permit/deny */ 10512 ntohs(iterator->addr.sin_port), status, 10513 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10514 10515 if (!s) {/* Normal CLI list */ 10516 ast_cli(fd, FORMAT, name, 10517 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10518 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10519 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10520 iterator->ha ? " A " : " ", /* permit/deny */ 10521 10522 ntohs(iterator->addr.sin_port), status, 10523 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10524 } else { /* Manager format */ 10525 /* The names here need to be the same as other channels */ 10526 astman_append(s, 10527 "Event: PeerEntry\r\n%s" 10528 "Channeltype: SIP\r\n" 10529 "ObjectName: %s\r\n" 10530 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 10531 "IPaddress: %s\r\n" 10532 "IPport: %d\r\n" 10533 "Dynamic: %s\r\n" 10534 "Natsupport: %s\r\n" 10535 "VideoSupport: %s\r\n" 10536 "ACL: %s\r\n" 10537 "Status: %s\r\n" 10538 "RealtimeDevice: %s\r\n\r\n", 10539 idtext, 10540 iterator->name, 10541 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 10542 ntohs(iterator->addr.sin_port), 10543 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 10544 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 10545 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 10546 iterator->ha ? "yes" : "no", /* permit/deny */ 10547 status, 10548 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 10549 } 10550 10551 ASTOBJ_UNLOCK(iterator); 10552 10553 total_peers++; 10554 } while(0) ); 10555 10556 if (!s) 10557 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 10558 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 10559 10560 if (havepattern) 10561 regfree(®exbuf); 10562 10563 if (total) 10564 *total = total_peers; 10565 10566 10567 return RESULT_SUCCESS; 10568 #undef FORMAT 10569 #undef FORMAT2 10570 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 15633 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.
15634 { 15635 struct ast_rtp_quality qos; 15636 struct sip_pvt *p = chan->tech_pvt; 15637 char *all = "", *parse = ast_strdupa(preparse); 15638 AST_DECLARE_APP_ARGS(args, 15639 AST_APP_ARG(param); 15640 AST_APP_ARG(type); 15641 AST_APP_ARG(field); 15642 ); 15643 AST_STANDARD_APP_ARGS(args, parse); 15644 15645 /* Sanity check */ 15646 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 15647 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 15648 return 0; 15649 } 15650 15651 if (strcasecmp(args.param, "rtpqos")) 15652 return 0; 15653 15654 /* Default arguments of audio,all */ 15655 if (ast_strlen_zero(args.type)) 15656 args.type = "audio"; 15657 if (ast_strlen_zero(args.field)) 15658 args.field = "all"; 15659 15660 memset(buf, 0, buflen); 15661 memset(&qos, 0, sizeof(qos)); 15662 15663 if (p == NULL) { 15664 return -1; 15665 } 15666 15667 if (strcasecmp(args.type, "AUDIO") == 0) { 15668 all = ast_rtp_get_quality(p->rtp, &qos); 15669 } else if (strcasecmp(args.type, "VIDEO") == 0) { 15670 all = ast_rtp_get_quality(p->vrtp, &qos); 15671 } 15672 15673 if (strcasecmp(args.field, "local_ssrc") == 0) 15674 snprintf(buf, buflen, "%u", qos.local_ssrc); 15675 else if (strcasecmp(args.field, "local_lostpackets") == 0) 15676 snprintf(buf, buflen, "%u", qos.local_lostpackets); 15677 else if (strcasecmp(args.field, "local_jitter") == 0) 15678 snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0); 15679 else if (strcasecmp(args.field, "local_count") == 0) 15680 snprintf(buf, buflen, "%u", qos.local_count); 15681 else if (strcasecmp(args.field, "remote_ssrc") == 0) 15682 snprintf(buf, buflen, "%u", qos.remote_ssrc); 15683 else if (strcasecmp(args.field, "remote_lostpackets") == 0) 15684 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 15685 else if (strcasecmp(args.field, "remote_jitter") == 0) 15686 snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0); 15687 else if (strcasecmp(args.field, "remote_count") == 0) 15688 snprintf(buf, buflen, "%u", qos.remote_count); 15689 else if (strcasecmp(args.field, "rtt") == 0) 15690 snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0); 15691 else if (strcasecmp(args.field, "all") == 0) 15692 ast_copy_string(buf, all, buflen); 15693 else { 15694 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 15695 return -1; 15696 } 15697 return 0; 15698 }
static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 2295 of file chan_sip.c.
References sip_request::data, sip_request::len, and sip_request::lines.
Referenced by send_request(), and send_response().
02296 { 02297 if (!req->lines) { 02298 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 02299 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 02300 req->len += strlen(req->data + req->len); 02301 } 02302 }
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 6566 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().
06569 { 06570 int rtp_code; 06571 struct ast_format_list fmt; 06572 06573 06574 if (debug) 06575 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 06576 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 06577 return; 06578 06579 if (p->rtp) { 06580 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 06581 fmt = ast_codec_pref_getsize(pref, codec); 06582 } 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 */ 06583 return; 06584 ast_build_string(m_buf, m_size, " %d", rtp_code); 06585 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06586 ast_rtp_lookup_mime_subtype(1, codec, 06587 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 06588 sample_rate); 06589 if (codec == AST_FORMAT_G729A) { 06590 /* Indicate that we don't support VAD (G.729 annex B) */ 06591 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 06592 } else if (codec == AST_FORMAT_G723_1) { 06593 /* Indicate that we don't support VAD (G.723.1 annex A) */ 06594 ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code); 06595 } else if (codec == AST_FORMAT_ILBC) { 06596 /* Add information about us using only 20/30 ms packetization */ 06597 ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 06598 } 06599 06600 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 06601 *min_packet_size = fmt.cur_ms; 06602 06603 /* Our first codec packetization processed cannot be less than zero */ 06604 if ((*min_packet_size) == 0 && fmt.cur_ms) 06605 *min_packet_size = fmt.cur_ms; 06606 }
static int add_digit | ( | struct sip_request * | req, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Add DTMF INFO tone to sip message.
Definition at line 6534 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_digit().
06535 { 06536 char tmp[256]; 06537 06538 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 06539 add_header(req, "Content-Type", "application/dtmf-relay"); 06540 add_header_contentLength(req, strlen(tmp)); 06541 add_line(req, tmp); 06542 return 0; 06543 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 5865 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.
05866 { 05867 int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */ 05868 05869 if (req->headers == SIP_MAX_HEADERS) { 05870 ast_log(LOG_WARNING, "Out of SIP header space\n"); 05871 return -1; 05872 } 05873 05874 if (req->lines) { 05875 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 05876 return -1; 05877 } 05878 05879 if (maxlen <= 0) { 05880 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 05881 return -1; 05882 } 05883 05884 req->header[req->headers] = req->data + req->len; 05885 05886 if (compactheaders) 05887 var = find_alias(var, var); 05888 05889 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 05890 req->len += strlen(req->header[req->headers]); 05891 req->headers++; 05892 05893 return 0; 05894 }
static int add_header_contentLength | ( | struct sip_request * | req, | |
int | len | |||
) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 5897 of file chan_sip.c.
References add_header().
Referenced by __transmit_response(), add_digit(), add_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().
05898 { 05899 char clen[10]; 05900 05901 snprintf(clen, sizeof(clen), "%d", len); 05902 return add_header(req, "Content-Length", clen); 05903 }
static int add_line | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 5906 of file chan_sip.c.
References ast_log(), sip_request::data, sip_request::len, sip_request::line, sip_request::lines, and SIP_MAX_LINES.
05907 { 05908 if (req->lines == SIP_MAX_LINES) { 05909 ast_log(LOG_WARNING, "Out of SIP line space\n"); 05910 return -1; 05911 } 05912 if (!req->lines) { 05913 /* Add extra empty return */ 05914 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 05915 req->len += strlen(req->data + req->len); 05916 } 05917 if (req->len >= sizeof(req->data) - 4) { 05918 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 05919 return -1; 05920 } 05921 req->line[req->lines] = req->data + req->len; 05922 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 05923 req->len += strlen(req->line[req->lines]); 05924 req->lines++; 05925 return 0; 05926 }
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 6645 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().
06648 { 06649 int rtp_code; 06650 06651 if (debug) 06652 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 06653 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 06654 return; 06655 06656 ast_build_string(m_buf, m_size, " %d", rtp_code); 06657 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06658 ast_rtp_lookup_mime_subtype(0, format, 0), 06659 sample_rate); 06660 if (format == AST_RTP_DTMF) 06661 /* Indicate we support DTMF and FLASH... */ 06662 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 06663 }
static struct sip_auth * add_realm_authentication | ( | struct sip_auth * | authlist, | |
char * | configuration, | |||
int | lineno | |||
) | [static] |
Add realm authentication in list.
Definition at line 17380 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().
17381 { 17382 char authcopy[256]; 17383 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 17384 char *stringp; 17385 struct sip_auth *a, *b, *auth; 17386 17387 if (ast_strlen_zero(configuration)) 17388 return authlist; 17389 17390 if (option_debug) 17391 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 17392 17393 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 17394 stringp = authcopy; 17395 17396 username = stringp; 17397 realm = strrchr(stringp, '@'); 17398 if (realm) 17399 *realm++ = '\0'; 17400 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 17401 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 17402 return authlist; 17403 } 17404 stringp = username; 17405 username = strsep(&stringp, ":"); 17406 if (username) { 17407 secret = strsep(&stringp, ":"); 17408 if (!secret) { 17409 stringp = username; 17410 md5secret = strsep(&stringp,"#"); 17411 } 17412 } 17413 if (!(auth = ast_calloc(1, sizeof(*auth)))) 17414 return authlist; 17415 17416 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 17417 ast_copy_string(auth->username, username, sizeof(auth->username)); 17418 if (secret) 17419 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 17420 if (md5secret) 17421 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 17422 17423 /* find the end of the list */ 17424 for (b = NULL, a = authlist; a ; b = a, a = a->next) 17425 ; 17426 if (b) 17427 b->next = auth; /* Add structure add end of list */ 17428 else 17429 authlist = auth; 17430 17431 if (option_verbose > 2) 17432 ast_verbose("Added authentication for realm %s\n", realm); 17433 17434 return authlist; 17435 17436 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 6027 of file chan_sip.c.
References add_header(), ast_copy_string(), sip_route::hop, sip_route::next, and SIPBUFSIZE.
Referenced by initreqprep(), and reqprep().
06028 { 06029 char r[SIPBUFSIZE*2], *p; 06030 int n, rem = sizeof(r); 06031 06032 if (!route) 06033 return; 06034 06035 p = r; 06036 for (;route ; route = route->next) { 06037 n = strlen(route->hop); 06038 if (rem < n+3) /* we need room for ",<route>" */ 06039 break; 06040 if (p != r) { /* add a separator after fist route */ 06041 *p++ = ','; 06042 --rem; 06043 } 06044 *p++ = '<'; 06045 ast_copy_string(p, route->hop, rem); /* cannot fail */ 06046 p += n; 06047 *p++ = '>'; 06048 rem -= (n+2); 06049 } 06050 *p = '\0'; 06051 add_header(req, "Route", r); 06052 }
static enum sip_result add_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p, | |||
int | add_audio, | |||
int | add_t38 | |||
) | [static] |
Add Session Description Protocol message.
Definition at line 6673 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_udptl_get_local_max_datagram(), ast_udptl_get_us(), ast_verbose(), t38properties::capability, capability, debug, FALSE, sip_pvt::flags, t38properties::jointcapability, 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, t38properties::peercapability, 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, 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, t38properties::t38support, TRUE, sip_pvt::udptl, sip_pvt::udptlredirip, sip_pvt::vredirip, and sip_pvt::vrtp.
06674 { 06675 int len = 0; 06676 int alreadysent = 0; 06677 06678 struct sockaddr_in sin; 06679 struct sockaddr_in vsin; 06680 struct sockaddr_in dest; 06681 struct sockaddr_in vdest = { 0, }; 06682 06683 /* SDP fields */ 06684 char *version = "v=0\r\n"; /* Protocol version */ 06685 char *subject = "s=session\r\n"; /* Subject of the session */ 06686 char owner[256]; /* Session owner/creator */ 06687 char connection[256]; /* Connection data */ 06688 char *stime = "t=0 0\r\n"; /* Time the session is active */ 06689 char bandwidth[256] = ""; /* Max bitrate */ 06690 char *hold; 06691 char m_audio[256]; /* Media declaration line for audio */ 06692 char m_video[256]; /* Media declaration line for video */ 06693 char m_modem[256]; /* Media declaration line for t38 */ 06694 char a_audio[1024]; /* Attributes for audio */ 06695 char a_video[1024]; /* Attributes for video */ 06696 char a_modem[1024]; /* Attributes for t38 */ 06697 char *m_audio_next = m_audio; 06698 char *m_video_next = m_video; 06699 char *m_modem_next = m_modem; 06700 size_t m_audio_left = sizeof(m_audio); 06701 size_t m_video_left = sizeof(m_video); 06702 size_t m_modem_left = sizeof(m_modem); 06703 char *a_audio_next = a_audio; 06704 char *a_video_next = a_video; 06705 char *a_modem_next = a_modem; 06706 size_t a_audio_left = sizeof(a_audio); 06707 size_t a_video_left = sizeof(a_video); 06708 size_t a_modem_left = sizeof(a_modem); 06709 06710 int x; 06711 int capability = 0; 06712 int needvideo = FALSE; 06713 int debug = sip_debug_test_pvt(p); 06714 int min_audio_packet_size = 0; 06715 int min_video_packet_size = 0; 06716 06717 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 06718 m_modem[0] = '\0'; 06719 06720 if (!p->rtp) { 06721 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 06722 return AST_FAILURE; 06723 } 06724 06725 /* Set RTP Session ID and version */ 06726 if (!p->sessionid) { 06727 p->sessionid = getpid(); 06728 p->sessionversion = p->sessionid; 06729 } else 06730 p->sessionversion++; 06731 06732 /* Get our addresses */ 06733 ast_rtp_get_us(p->rtp, &sin); 06734 if (p->vrtp) 06735 ast_rtp_get_us(p->vrtp, &vsin); 06736 06737 /* Is this a re-invite to move the media out, then use the original offer from caller */ 06738 if (p->redirip.sin_addr.s_addr) { 06739 dest.sin_port = p->redirip.sin_port; 06740 dest.sin_addr = p->redirip.sin_addr; 06741 } else { 06742 dest.sin_addr = p->ourip; 06743 dest.sin_port = sin.sin_port; 06744 } 06745 06746 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 06747 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 06748 06749 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) 06750 hold = "a=recvonly\r\n"; 06751 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) 06752 hold = "a=inactive\r\n"; 06753 else 06754 hold = "a=sendrecv\r\n"; 06755 06756 if (add_audio) { 06757 capability = p->jointcapability; 06758 06759 06760 if (option_debug > 1) { 06761 char codecbuf[SIPBUFSIZE]; 06762 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"); 06763 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 06764 } 06765 06766 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 06767 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 06768 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 06769 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 06770 } 06771 #endif 06772 06773 /* Check if we need video in this call */ 06774 if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 06775 if (p->vrtp) { 06776 needvideo = TRUE; 06777 if (option_debug > 1) 06778 ast_log(LOG_DEBUG, "This call needs video offers!\n"); 06779 } else if (option_debug > 1) 06780 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n"); 06781 } 06782 06783 06784 /* Ok, we need video. Let's add what we need for video and set codecs. 06785 Video is handled differently than audio since we can not transcode. */ 06786 if (needvideo) { 06787 /* Determine video destination */ 06788 if (p->vredirip.sin_addr.s_addr) { 06789 vdest.sin_addr = p->vredirip.sin_addr; 06790 vdest.sin_port = p->vredirip.sin_port; 06791 } else { 06792 vdest.sin_addr = p->ourip; 06793 vdest.sin_port = vsin.sin_port; 06794 } 06795 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 06796 06797 /* Build max bitrate string */ 06798 if (p->maxcallbitrate) 06799 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 06800 if (debug) 06801 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 06802 } 06803 06804 if (debug) 06805 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 06806 06807 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 06808 06809 /* Now, start adding audio codecs. These are added in this order: 06810 - First what was requested by the calling channel 06811 - Then preferences in order from sip.conf device config for this peer/user 06812 - Then other codecs in capabilities, including video 06813 */ 06814 06815 /* Prefer the audio codec we were requested to use, first, no matter what 06816 Note that p->prefcodec can include video codecs, so mask them out 06817 */ 06818 if (capability & p->prefcodec) { 06819 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 06820 06821 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06822 &m_audio_next, &m_audio_left, 06823 &a_audio_next, &a_audio_left, 06824 debug, &min_audio_packet_size); 06825 alreadysent |= codec; 06826 } 06827 06828 /* Start by sending our preferred audio codecs */ 06829 for (x = 0; x < 32; x++) { 06830 int codec; 06831 06832 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 06833 break; 06834 06835 if (!(capability & codec)) 06836 continue; 06837 06838 if (alreadysent & codec) 06839 continue; 06840 06841 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06842 &m_audio_next, &m_audio_left, 06843 &a_audio_next, &a_audio_left, 06844 debug, &min_audio_packet_size); 06845 alreadysent |= codec; 06846 } 06847 06848 /* Now send any other common audio and video codecs, and non-codec formats: */ 06849 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 06850 if (!(capability & x)) /* Codec not requested */ 06851 continue; 06852 06853 if (alreadysent & x) /* Already added to SDP */ 06854 continue; 06855 06856 if (x <= AST_FORMAT_MAX_AUDIO) 06857 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 06858 &m_audio_next, &m_audio_left, 06859 &a_audio_next, &a_audio_left, 06860 debug, &min_audio_packet_size); 06861 else 06862 add_codec_to_sdp(p, x, 90000, 06863 &m_video_next, &m_video_left, 06864 &a_video_next, &a_video_left, 06865 debug, &min_video_packet_size); 06866 } 06867 06868 /* Now add DTMF RFC2833 telephony-event as a codec */ 06869 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 06870 if (!(p->jointnoncodeccapability & x)) 06871 continue; 06872 06873 add_noncodec_to_sdp(p, x, 8000, 06874 &m_audio_next, &m_audio_left, 06875 &a_audio_next, &a_audio_left, 06876 debug); 06877 } 06878 06879 if (option_debug > 2) 06880 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 06881 06882 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 06883 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 06884 06885 if (min_audio_packet_size) 06886 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 06887 06888 if (min_video_packet_size) 06889 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 06890 06891 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 06892 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 06893 06894 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 06895 if (needvideo) 06896 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 06897 } 06898 06899 if (add_t38 && p->udptl) { 06900 struct sockaddr_in udptlsin; 06901 struct sockaddr_in udptldest = { 0, }; 06902 06903 ast_udptl_get_us(p->udptl, &udptlsin); 06904 06905 if (p->udptlredirip.sin_addr.s_addr) { 06906 udptldest.sin_port = p->udptlredirip.sin_port; 06907 udptldest.sin_addr = p->udptlredirip.sin_addr; 06908 } else { 06909 udptldest.sin_addr = p->ourip; 06910 udptldest.sin_port = udptlsin.sin_port; 06911 } 06912 06913 if (debug) { 06914 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 06915 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 06916 p->t38.capability, 06917 p->t38.peercapability, 06918 p->t38.jointcapability); 06919 } 06920 06921 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 06922 06923 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 06924 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 06925 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 06926 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 06927 if ((x = t38_get_rate(p->t38.jointcapability))) 06928 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 06929 if ((p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) == T38FAX_FILL_BIT_REMOVAL) 06930 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval\r\n"); 06931 if ((p->t38.jointcapability & T38FAX_TRANSCODING_MMR) == T38FAX_TRANSCODING_MMR) 06932 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR\r\n"); 06933 if ((p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) == T38FAX_TRANSCODING_JBIG) 06934 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG\r\n"); 06935 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 06936 x = ast_udptl_get_local_max_datagram(p->udptl); 06937 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 06938 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 06939 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 06940 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 06941 } 06942 06943 len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime); 06944 if (add_audio) 06945 len += strlen(m_audio) + strlen(a_audio) + strlen(hold); 06946 if (needvideo) /* only if video response is appropriate */ 06947 len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold); 06948 if (add_t38) { 06949 len += strlen(m_modem) + strlen(a_modem); 06950 } 06951 06952 add_header(resp, "Content-Type", "application/sdp"); 06953 add_header_contentLength(resp, len); 06954 add_line(resp, version); 06955 add_line(resp, owner); 06956 add_line(resp, subject); 06957 add_line(resp, connection); 06958 if (needvideo) /* only if video response is appropriate */ 06959 add_line(resp, bandwidth); 06960 add_line(resp, stime); 06961 if (add_audio) { 06962 add_line(resp, m_audio); 06963 add_line(resp, a_audio); 06964 add_line(resp, hold); 06965 } 06966 if (needvideo) { /* only if video response is appropriate */ 06967 add_line(resp, m_video); 06968 add_line(resp, a_video); 06969 add_line(resp, hold); /* Repeat hold for the video stream */ 06970 } 06971 if (add_t38) { 06972 add_line(resp, m_modem); 06973 add_line(resp, a_modem); 06974 } 06975 06976 /* Update lastrtprx when we send our SDP */ 06977 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 06978 06979 if (option_debug > 2) { 06980 char buf[SIPBUFSIZE]; 06981 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability)); 06982 } 06983 06984 return AST_SUCCESS; 06985 }
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 17316 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.
17317 { 17318 struct domain *d; 17319 17320 if (ast_strlen_zero(domain)) { 17321 ast_log(LOG_WARNING, "Zero length domain.\n"); 17322 return 1; 17323 } 17324 17325 if (!(d = ast_calloc(1, sizeof(*d)))) 17326 return 0; 17327 17328 ast_copy_string(d->domain, domain, sizeof(d->domain)); 17329 17330 if (!ast_strlen_zero(context)) 17331 ast_copy_string(d->context, context, sizeof(d->context)); 17332 17333 d->mode = mode; 17334 17335 AST_LIST_LOCK(&domain_list); 17336 AST_LIST_INSERT_TAIL(&domain_list, d, list); 17337 AST_LIST_UNLOCK(&domain_list); 17338 17339 if (sipdebug) 17340 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 17341 17342 return 1; 17343 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 6523 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_message_with_text().
06524 { 06525 /* XXX Convert \n's to \r\n's XXX */ 06526 add_header(req, "Content-Type", "text/plain"); 06527 add_header_contentLength(req, strlen(text)); 06528 add_line(req, text); 06529 return 0; 06530 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 6547 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_vidupdate().
06548 { 06549 const char *xml_is_a_huge_waste_of_space = 06550 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 06551 " <media_control>\r\n" 06552 " <vc_primitive>\r\n" 06553 " <to_encoder>\r\n" 06554 " <picture_fast_update>\r\n" 06555 " </picture_fast_update>\r\n" 06556 " </to_encoder>\r\n" 06557 " </vc_primitive>\r\n" 06558 " </media_control>\r\n"; 06559 add_header(req, "Content-Type", "application/media_control+xml"); 06560 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 06561 add_line(req, xml_is_a_huge_waste_of_space); 06562 return 0; 06563 }
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 6470 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().
06471 { 06472 char tmpdat[256]; 06473 struct tm tm; 06474 time_t t = time(NULL); 06475 06476 gmtime_r(&t, &tm); 06477 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 06478 add_header(req, "Date", tmpdat); 06479 }
static void append_history_full | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1907 of file chan_sip.c.
References append_history_va(), ast_test_flag, sip_pvt::flags, and SIP_NO_HISTORY.
01908 { 01909 va_list ap; 01910 01911 if (!p) 01912 return; 01913 01914 if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY) 01915 && !recordhistory && !dumphistory) { 01916 return; 01917 } 01918 01919 va_start(ap, fmt); 01920 append_history_va(p, fmt, ap); 01921 va_end(ap); 01922 01923 return; 01924 }
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 1880 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().
01881 { 01882 char buf[80], *c = buf; /* max history length */ 01883 struct sip_history *hist; 01884 int l; 01885 01886 vsnprintf(buf, sizeof(buf), fmt, ap); 01887 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 01888 l = strlen(buf) + 1; 01889 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) 01890 return; 01891 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 01892 free(hist); 01893 return; 01894 } 01895 memcpy(hist->event, buf, l); 01896 if (p->history_entries == MAX_HISTORY_ENTRIES) { 01897 struct sip_history *oldest; 01898 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 01899 p->history_entries--; 01900 free(oldest); 01901 } 01902 AST_LIST_INSERT_TAIL(p->history, hist, list); 01903 p->history_entries++; 01904 }
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 13819 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().
13820 { 13821 if (chan && chan->_state == AST_STATE_UP) { 13822 if (ast_test_flag(chan, AST_FLAG_MOH)) 13823 ast_moh_stop(chan); 13824 else if (chan->generatordata) 13825 ast_deactivate_generator(chan); 13826 } 13827 }
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 1840 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().
01841 { 01842 struct sockaddr_in theirs, ours; 01843 01844 /* Get our local information */ 01845 ast_ouraddrfor(them, us); 01846 theirs.sin_addr = *them; 01847 ours.sin_addr = *us; 01848 01849 if (localaddr && externip.sin_addr.s_addr && 01850 (ast_apply_ha(localaddr, &theirs)) && 01851 (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) { 01852 if (externexpire && time(NULL) >= externexpire) { 01853 struct ast_hostent ahp; 01854 struct hostent *hp; 01855 01856 externexpire = time(NULL) + externrefresh; 01857 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01858 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01859 } else 01860 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01861 } 01862 *us = externip.sin_addr; 01863 if (option_debug) { 01864 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 01865 ast_inet_ntoa(*(struct in_addr *)&them->s_addr)); 01866 } 01867 } else if (bindaddr.sin_addr.s_addr) 01868 *us = bindaddr.sin_addr; 01869 return AST_SUCCESS; 01870 }
Attempt transfer of SIP call This fix for attended transfers on a local PBX.
Definition at line 13831 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.
13832 { 13833 int res = 0; 13834 struct ast_channel *peera = NULL, 13835 *peerb = NULL, 13836 *peerc = NULL, 13837 *peerd = NULL; 13838 13839 13840 /* We will try to connect the transferee with the target and hangup 13841 all channels to the transferer */ 13842 if (option_debug > 3) { 13843 ast_log(LOG_DEBUG, "Sip transfer:--------------------\n"); 13844 if (transferer->chan1) 13845 ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 13846 else 13847 ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n"); 13848 if (target->chan1) 13849 ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 13850 else 13851 ast_log(LOG_DEBUG, "-- No target first channel ---\n"); 13852 if (transferer->chan2) 13853 ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 13854 else 13855 ast_log(LOG_DEBUG, "-- No bridged call to transferee\n"); 13856 if (target->chan2) 13857 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)"); 13858 else 13859 ast_log(LOG_DEBUG, "-- No target second channel ---\n"); 13860 ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n"); 13861 } 13862 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 13863 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 13864 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 13865 peerc = transferer->chan2; /* Asterisk to Transferee */ 13866 peerd = target->chan2; /* Asterisk to Target */ 13867 if (option_debug > 2) 13868 ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n"); 13869 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 13870 peera = target->chan1; /* Transferer to PBX -> target channel */ 13871 peerb = transferer->chan1; /* Transferer to IVR*/ 13872 peerc = target->chan2; /* Asterisk to Target */ 13873 peerd = transferer->chan2; /* Nothing */ 13874 if (option_debug > 2) 13875 ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n"); 13876 } 13877 13878 if (peera && peerb && peerc && (peerb != peerc)) { 13879 ast_quiet_chan(peera); /* Stop generators */ 13880 ast_quiet_chan(peerb); 13881 ast_quiet_chan(peerc); 13882 if (peerd) 13883 ast_quiet_chan(peerd); 13884 13885 if (option_debug > 3) 13886 ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 13887 if (ast_channel_masquerade(peerb, peerc)) { 13888 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 13889 res = -1; 13890 } else 13891 ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n"); 13892 return res; 13893 } else { 13894 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 13895 if (transferer->chan1) 13896 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 13897 if (target->chan1) 13898 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 13899 return -2; 13900 } 13901 return 0; 13902 }
static int auto_congest | ( | const void * | nothing | ) | [static] |
Scheduled congestion on a call.
Definition at line 3016 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.
03017 { 03018 struct sip_pvt *p = (struct sip_pvt *)nothing; 03019 03020 ast_mutex_lock(&p->lock); 03021 p->initid = -1; 03022 if (p->owner) { 03023 /* XXX fails on possible deadlock */ 03024 if (!ast_channel_trylock(p->owner)) { 03025 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 03026 append_history(p, "Cong", "Auto-congesting (timer)"); 03027 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 03028 ast_channel_unlock(p->owner); 03029 } 03030 } 03031 ast_mutex_unlock(&p->lock); 03032 return 0; 03033 }
static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 4565 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().
04566 { 04567 char buf[33]; 04568 04569 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip)); 04570 04571 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04572 04573 }
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 4576 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().
04577 { 04578 char buf[33]; 04579 04580 const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip)); 04581 04582 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04583 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 7160 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().
07161 { 07162 /* Construct Contact: header */ 07163 if (ourport != STANDARD_SIP_PORT) 07164 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); 07165 else 07166 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip)); 07167 }
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 17647 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_REF, 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::lastms, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, LOG_ERROR, 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_NAT_ROUTE, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_SUBSCRIBEMWIONLY, sip_poke_peer(), SIP_REALTIME, SIP_USEREQPHONE, STANDARD_SIP_PORT, sip_peer::subscribecontext, sip_peer::tohost, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, sip_peer::username, ast_variable::value, and sip_peer::vmexten.
17648 { 17649 struct sip_peer *peer = NULL; 17650 struct ast_ha *oldha = NULL; 17651 int obproxyfound=0; 17652 int found=0; 17653 int firstpass=1; 17654 int format=0; /* Ama flags */ 17655 time_t regseconds = 0; 17656 char *varname = NULL, *varval = NULL; 17657 struct ast_variable *tmpvar = NULL; 17658 struct ast_flags peerflags[2] = {{(0)}}; 17659 struct ast_flags mask[2] = {{(0)}}; 17660 int alt_fullcontact = alt ? 1 : 0; 17661 char fullcontact[sizeof(peer->fullcontact)] = ""; 17662 17663 if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 17664 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 17665 /* We also use a case-sensitive comparison (unlike find_peer) so 17666 that case changes made to the peer name will be properly handled 17667 during reload 17668 */ 17669 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 17670 17671 if (peer) { 17672 /* Already in the list, remove it and it will be added back (or FREE'd) */ 17673 found = 1; 17674 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 17675 firstpass = 0; 17676 } else { 17677 if (!(peer = ast_calloc(1, sizeof(*peer)))) 17678 return NULL; 17679 17680 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 17681 rpeerobjs++; 17682 else 17683 speerobjs++; 17684 ASTOBJ_INIT(peer); 17685 } 17686 /* Note that our peer HAS had its reference count incrased */ 17687 if (firstpass) { 17688 peer->lastmsgssent = -1; 17689 oldha = peer->ha; 17690 peer->ha = NULL; 17691 set_peer_defaults(peer); /* Set peer defaults */ 17692 } 17693 if (!found && name) 17694 ast_copy_string(peer->name, name, sizeof(peer->name)); 17695 17696 /* If we have channel variables, remove them (reload) */ 17697 if (peer->chanvars) { 17698 ast_variables_destroy(peer->chanvars); 17699 peer->chanvars = NULL; 17700 /* XXX should unregister ? */ 17701 } 17702 17703 /* If we have realm authentication information, remove them (reload) */ 17704 clear_realm_authentication(peer->auth); 17705 peer->auth = NULL; 17706 17707 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 17708 if (handle_common_options(&peerflags[0], &mask[0], v)) 17709 continue; 17710 if (realtime && !strcasecmp(v->name, "regseconds")) { 17711 ast_get_time_t(v->value, ®seconds, 0, NULL); 17712 } else if (realtime && !strcasecmp(v->name, "lastms")) { 17713 sscanf(v->value, "%30d", &peer->lastms); 17714 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 17715 inet_aton(v->value, &(peer->addr.sin_addr)); 17716 } else if (realtime && !strcasecmp(v->name, "name")) 17717 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 17718 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 17719 if (alt_fullcontact && !alt) { 17720 /* Reset, because the alternate also has a fullcontact and we 17721 * do NOT want the field value to be doubled. It might be 17722 * tempting to skip this, but the first table might not have 17723 * fullcontact and since we're here, we know that the alternate 17724 * absolutely does. */ 17725 alt_fullcontact = 0; 17726 fullcontact[0] = '\0'; 17727 } 17728 /* Reconstruct field, because realtime separates our value at the ';' */ 17729 if (!ast_strlen_zero(fullcontact)) { 17730 strncat(fullcontact, ";", sizeof(fullcontact) - strlen(fullcontact) - 1); 17731 strncat(fullcontact, v->value, sizeof(fullcontact) - strlen(fullcontact) - 1); 17732 } else { 17733 ast_copy_string(fullcontact, v->value, sizeof(fullcontact)); 17734 ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT); 17735 } 17736 } else if (!strcasecmp(v->name, "secret")) 17737 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 17738 else if (!strcasecmp(v->name, "md5secret")) 17739 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 17740 else if (!strcasecmp(v->name, "auth")) 17741 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 17742 else if (!strcasecmp(v->name, "callerid")) { 17743 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 17744 } else if (!strcasecmp(v->name, "fullname")) { 17745 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 17746 } else if (!strcasecmp(v->name, "cid_number")) { 17747 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 17748 } else if (!strcasecmp(v->name, "context")) { 17749 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 17750 } else if (!strcasecmp(v->name, "subscribecontext")) { 17751 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 17752 } else if (!strcasecmp(v->name, "fromdomain")) { 17753 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 17754 } else if (!strcasecmp(v->name, "usereqphone")) { 17755 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 17756 } else if (!strcasecmp(v->name, "fromuser")) { 17757 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 17758 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 17759 if (!strcasecmp(v->value, "dynamic")) { 17760 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 17761 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 17762 } else { 17763 /* They'll register with us */ 17764 if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 17765 /* Initialize stuff if this is a new peer, or if it used to be 17766 * non-dynamic before the reload. */ 17767 memset(&peer->addr.sin_addr, 0, 4); 17768 if (peer->addr.sin_port) { 17769 /* If we've already got a port, make it the default rather than absolute */ 17770 peer->defaddr.sin_port = peer->addr.sin_port; 17771 peer->addr.sin_port = 0; 17772 } 17773 } 17774 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 17775 } 17776 } else { 17777 /* Non-dynamic. Make sure we become that way if we're not */ 17778 if (!AST_SCHED_DEL(sched, peer->expire)) { 17779 struct sip_peer *peer_ptr = peer; 17780 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17781 } 17782 ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 17783 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 17784 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 17785 ast_log(LOG_ERROR, "srvlookup failed for outboundproxy: %s, on peer %s, removing peer\n", v->value, peer->name); 17786 ASTOBJ_UNREF(peer, sip_destroy_peer); 17787 return NULL; 17788 } 17789 } 17790 if (!strcasecmp(v->name, "outboundproxy")) 17791 obproxyfound=1; 17792 else { 17793 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 17794 if (!peer->addr.sin_port) 17795 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 17796 } 17797 if (global_dynamic_exclude_static) { 17798 global_contact_ha = ast_append_ha("deny", (char *)ast_inet_ntoa(peer->addr.sin_addr), global_contact_ha); 17799 } 17800 } 17801 } else if (!strcasecmp(v->name, "defaultip")) { 17802 if (ast_get_ip(&peer->defaddr, v->value)) { 17803 ASTOBJ_UNREF(peer, sip_destroy_peer); 17804 return NULL; 17805 } 17806 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 17807 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 17808 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 17809 peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha); 17810 } else if (!strcasecmp(v->name, "port")) { 17811 if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) 17812 peer->defaddr.sin_port = htons(atoi(v->value)); 17813 else 17814 peer->addr.sin_port = htons(atoi(v->value)); 17815 } else if (!strcasecmp(v->name, "callingpres")) { 17816 peer->callingpres = ast_parse_caller_presentation(v->value); 17817 if (peer->callingpres == -1) 17818 peer->callingpres = atoi(v->value); 17819 } else if (!strcasecmp(v->name, "username")) { 17820 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 17821 } else if (!strcasecmp(v->name, "language")) { 17822 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 17823 } else if (!strcasecmp(v->name, "regexten")) { 17824 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 17825 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 17826 peer->call_limit = atoi(v->value); 17827 if (peer->call_limit < 0) 17828 peer->call_limit = 0; 17829 } else if (!strcasecmp(v->name, "amaflags")) { 17830 format = ast_cdr_amaflags2int(v->value); 17831 if (format < 0) { 17832 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 17833 } else { 17834 peer->amaflags = format; 17835 } 17836 } else if (!strcasecmp(v->name, "accountcode")) { 17837 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 17838 } else if (!strcasecmp(v->name, "mohinterpret") 17839 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17840 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 17841 } else if (!strcasecmp(v->name, "mohsuggest")) { 17842 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 17843 } else if (!strcasecmp(v->name, "mailbox")) { 17844 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 17845 } else if (!strcasecmp(v->name, "hasvoicemail")) { 17846 /* People expect that if 'hasvoicemail' is set, that the mailbox will 17847 * be also set, even if not explicitly specified. */ 17848 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 17849 ast_copy_string(peer->mailbox, name, sizeof(peer->mailbox)); 17850 } 17851 } else if (!strcasecmp(v->name, "subscribemwi")) { 17852 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 17853 } else if (!strcasecmp(v->name, "vmexten")) { 17854 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 17855 } else if (!strcasecmp(v->name, "callgroup")) { 17856 peer->callgroup = ast_get_group(v->value); 17857 } else if (!strcasecmp(v->name, "allowtransfer")) { 17858 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17859 } else if (!strcasecmp(v->name, "pickupgroup")) { 17860 peer->pickupgroup = ast_get_group(v->value); 17861 } else if (!strcasecmp(v->name, "allow")) { 17862 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 17863 } else if (!strcasecmp(v->name, "disallow")) { 17864 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 17865 } else if (!strcasecmp(v->name, "autoframing")) { 17866 peer->autoframing = ast_true(v->value); 17867 } else if (!strcasecmp(v->name, "rtptimeout")) { 17868 if ((sscanf(v->value, "%30d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 17869 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17870 peer->rtptimeout = global_rtptimeout; 17871 } 17872 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 17873 if ((sscanf(v->value, "%30d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 17874 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17875 peer->rtpholdtimeout = global_rtpholdtimeout; 17876 } 17877 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 17878 if ((sscanf(v->value, "%30d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 17879 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 17880 peer->rtpkeepalive = global_rtpkeepalive; 17881 } 17882 } else if (!strcasecmp(v->name, "setvar")) { 17883 /* Set peer channel variable */ 17884 varname = ast_strdupa(v->value); 17885 if ((varval = strchr(varname, '='))) { 17886 *varval++ = '\0'; 17887 if ((tmpvar = ast_variable_new(varname, varval))) { 17888 tmpvar->next = peer->chanvars; 17889 peer->chanvars = tmpvar; 17890 } 17891 } 17892 } else if (!strcasecmp(v->name, "qualify")) { 17893 if (!strcasecmp(v->value, "no")) { 17894 peer->maxms = 0; 17895 } else if (!strcasecmp(v->value, "yes")) { 17896 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 17897 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 17898 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); 17899 peer->maxms = 0; 17900 } 17901 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) { 17902 /* This would otherwise cause a network storm, where the 17903 * qualify response refreshes the peer from the database, 17904 * which in turn causes another qualify to be sent, ad 17905 * infinitum. */ 17906 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); 17907 peer->maxms = 0; 17908 } 17909 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17910 peer->maxcallbitrate = atoi(v->value); 17911 if (peer->maxcallbitrate < 0) 17912 peer->maxcallbitrate = default_maxcallbitrate; 17913 } 17914 } 17915 if (!ast_strlen_zero(fullcontact)) { 17916 ast_copy_string(peer->fullcontact, fullcontact, sizeof(peer->fullcontact)); 17917 /* We have a hostname in the fullcontact, but if we don't have an 17918 * address listed on the entry (or if it's 'dynamic'), then we need to 17919 * parse the entry to obtain the IP address, so a dynamic host can be 17920 * contacted immediately after reload (as opposed to waiting for it to 17921 * register once again). But if we have an address for this peer and NAT was 17922 * specified, use that address instead. */ 17923 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE) || !peer->addr.sin_addr.s_addr) { 17924 __set_address_from_contact(fullcontact, &peer->addr); 17925 } 17926 } 17927 17928 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) { 17929 time_t nowtime = time(NULL); 17930 17931 if ((nowtime - regseconds) > 0) { 17932 destroy_association(peer); 17933 memset(&peer->addr, 0, sizeof(peer->addr)); 17934 peer->lastms = -1; 17935 if (option_debug) 17936 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 17937 } 17938 } 17939 17940 /* Startup regular pokes */ 17941 if (realtime && peer->lastms > 0) { 17942 ASTOBJ_REF(peer); 17943 sip_poke_peer(peer); 17944 } 17945 17946 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 17947 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 17948 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 17949 global_allowsubscribe = TRUE; /* No global ban any more */ 17950 if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME)) 17951 reg_source_db(peer); 17952 ASTOBJ_UNMARK(peer); 17953 ast_free_ha(oldha); 17954 return peer; 17955 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 12091 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, option_debug, 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().
12092 { 12093 char a1[256]; 12094 char a2[256]; 12095 char a1_hash[256]; 12096 char a2_hash[256]; 12097 char resp[256]; 12098 char resp_hash[256]; 12099 char uri[256]; 12100 char opaque[256] = ""; 12101 char cnonce[80]; 12102 const char *username; 12103 const char *secret; 12104 const char *md5secret; 12105 struct sip_auth *auth = NULL; /* Realm authentication */ 12106 12107 if (!ast_strlen_zero(p->domain)) 12108 ast_copy_string(uri, p->domain, sizeof(uri)); 12109 else if (!ast_strlen_zero(p->uri)) 12110 ast_copy_string(uri, p->uri, sizeof(uri)); 12111 else 12112 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr)); 12113 12114 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 12115 12116 /* Check if we have separate auth credentials */ 12117 if(!(auth = find_realm_authentication(p->peerauth, p->realm))) /* Start with peer list */ 12118 auth = find_realm_authentication(authl, p->realm); /* If not, global list */ 12119 12120 if (auth) { 12121 if (sipdebug && option_debug > 1) 12122 ast_log(LOG_DEBUG, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username); 12123 username = auth->username; 12124 secret = auth->secret; 12125 md5secret = auth->md5secret; 12126 if (sipdebug) 12127 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 12128 } else { 12129 /* No authentication, use peer or register= config */ 12130 username = p->authname; 12131 secret = p->peersecret; 12132 md5secret = p->peermd5secret; 12133 } 12134 if (ast_strlen_zero(username)) /* We have no authentication */ 12135 return -1; 12136 12137 /* Calculate SIP digest response */ 12138 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 12139 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 12140 if (!ast_strlen_zero(md5secret)) 12141 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 12142 else 12143 ast_md5_hash(a1_hash,a1); 12144 ast_md5_hash(a2_hash,a2); 12145 12146 p->noncecount++; 12147 if (!ast_strlen_zero(p->qop)) 12148 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 12149 else 12150 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 12151 ast_md5_hash(resp_hash, resp); 12152 12153 /* only include the opaque string if it's set */ 12154 if (!ast_strlen_zero(p->opaque)) { 12155 snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque); 12156 } 12157 12158 /* XXX We hard code our qop to "auth" for now. XXX */ 12159 if (!ast_strlen_zero(p->qop)) 12160 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); 12161 else 12162 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); 12163 12164 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 12165 12166 return 0; 12167 }
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 8635 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(), handle_request_subscribe(), and handle_response_invite().
08636 { 08637 struct sip_route *thishop, *head, *tail; 08638 int start = 0; 08639 int len; 08640 const char *rr, *contact, *c; 08641 08642 /* Once a persistant route is set, don't fool with it */ 08643 if (p->route && p->route_persistant) { 08644 if (option_debug) 08645 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 08646 return; 08647 } 08648 08649 if (p->route) { 08650 free_old_route(p->route); 08651 p->route = NULL; 08652 } 08653 08654 /* We only want to create the route set the first time this is called */ 08655 p->route_persistant = 1; 08656 08657 /* Build a tailq, then assign it to p->route when done. 08658 * If backwards, we add entries from the head so they end up 08659 * in reverse order. However, we do need to maintain a correct 08660 * tail pointer because the contact is always at the end. 08661 */ 08662 head = NULL; 08663 tail = head; 08664 /* 1st we pass through all the hops in any Record-Route headers */ 08665 for (;;) { 08666 /* Each Record-Route header */ 08667 rr = __get_header(req, "Record-Route", &start); 08668 if (*rr == '\0') 08669 break; 08670 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 08671 ++rr; 08672 len = strcspn(rr, ">") + 1; 08673 /* Make a struct route */ 08674 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08675 /* ast_calloc is not needed because all fields are initialized in this block */ 08676 ast_copy_string(thishop->hop, rr, len); 08677 if (option_debug > 1) 08678 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 08679 /* Link in */ 08680 if (backwards) { 08681 /* Link in at head so they end up in reverse order */ 08682 thishop->next = head; 08683 head = thishop; 08684 /* If this was the first then it'll be the tail */ 08685 if (!tail) 08686 tail = thishop; 08687 } else { 08688 thishop->next = NULL; 08689 /* Link in at the end */ 08690 if (tail) 08691 tail->next = thishop; 08692 else 08693 head = thishop; 08694 tail = thishop; 08695 } 08696 } 08697 } 08698 } 08699 08700 /* Only append the contact if we are dealing with a strict router */ 08701 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 08702 /* 2nd append the Contact: if there is one */ 08703 /* Can be multiple Contact headers, comma separated values - we just take the first */ 08704 contact = get_header(req, "Contact"); 08705 if (!ast_strlen_zero(contact)) { 08706 if (option_debug > 1) 08707 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 08708 /* Look for <: delimited address */ 08709 c = strchr(contact, '<'); 08710 if (c) { 08711 /* Take to > */ 08712 ++c; 08713 len = strcspn(c, ">") + 1; 08714 } else { 08715 /* No <> - just take the lot */ 08716 c = contact; 08717 len = strlen(contact) + 1; 08718 } 08719 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08720 /* ast_calloc is not needed because all fields are initialized in this block */ 08721 ast_copy_string(thishop->hop, c, len); 08722 thishop->next = NULL; 08723 /* Goes at the end */ 08724 if (tail) 08725 tail->next = thishop; 08726 else 08727 head = thishop; 08728 } 08729 } 08730 } 08731 08732 /* Store as new route */ 08733 p->route = head; 08734 08735 /* For debugging dump what we ended up with */ 08736 if (sip_debug_test_pvt(p)) 08737 list_route(p->route); 08738 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 7170 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().
07171 { 07172 int send_pres_tags = TRUE; 07173 const char *privacy=NULL; 07174 const char *screen=NULL; 07175 char buf[256]; 07176 const char *clid = default_callerid; 07177 const char *clin = NULL; 07178 const char *fromdomain; 07179 07180 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 07181 return; 07182 07183 if (p->owner && p->owner->cid.cid_num) 07184 clid = p->owner->cid.cid_num; 07185 if (p->owner && p->owner->cid.cid_name) 07186 clin = p->owner->cid.cid_name; 07187 if (ast_strlen_zero(clin)) 07188 clin = clid; 07189 07190 switch (p->callingpres) { 07191 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 07192 privacy = "off"; 07193 screen = "no"; 07194 break; 07195 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 07196 privacy = "off"; 07197 screen = "yes"; 07198 break; 07199 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 07200 privacy = "off"; 07201 screen = "no"; 07202 break; 07203 case AST_PRES_ALLOWED_NETWORK_NUMBER: 07204 privacy = "off"; 07205 screen = "yes"; 07206 break; 07207 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 07208 privacy = "full"; 07209 screen = "no"; 07210 break; 07211 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 07212 privacy = "full"; 07213 screen = "yes"; 07214 break; 07215 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 07216 privacy = "full"; 07217 screen = "no"; 07218 break; 07219 case AST_PRES_PROHIB_NETWORK_NUMBER: 07220 privacy = "full"; 07221 screen = "yes"; 07222 break; 07223 case AST_PRES_NUMBER_NOT_AVAILABLE: 07224 send_pres_tags = FALSE; 07225 break; 07226 default: 07227 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 07228 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 07229 privacy = "full"; 07230 else 07231 privacy = "off"; 07232 screen = "no"; 07233 break; 07234 } 07235 07236 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 07237 07238 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 07239 if (send_pres_tags) 07240 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 07241 ast_string_field_set(p, rpid, buf); 07242 07243 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 07244 S_OR(p->fromuser, clid), 07245 fromdomain, p->tag); 07246 }
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 17467 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.
17468 { 17469 struct sip_user *user; 17470 int format; 17471 struct ast_ha *oldha = NULL; 17472 char *varname = NULL, *varval = NULL; 17473 struct ast_variable *tmpvar = NULL; 17474 struct ast_flags userflags[2] = {{(0)}}; 17475 struct ast_flags mask[2] = {{(0)}}; 17476 17477 17478 if (!(user = ast_calloc(1, sizeof(*user)))) 17479 return NULL; 17480 17481 suserobjs++; 17482 ASTOBJ_INIT(user); 17483 ast_copy_string(user->name, name, sizeof(user->name)); 17484 oldha = user->ha; 17485 user->ha = NULL; 17486 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 17487 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 17488 user->capability = global_capability; 17489 user->allowtransfer = global_allowtransfer; 17490 user->maxcallbitrate = default_maxcallbitrate; 17491 user->autoframing = global_autoframing; 17492 user->prefs = default_prefs; 17493 /* set default context */ 17494 strcpy(user->context, default_context); 17495 strcpy(user->language, default_language); 17496 strcpy(user->mohinterpret, default_mohinterpret); 17497 strcpy(user->mohsuggest, default_mohsuggest); 17498 /* First we walk through the v parameters list and then the alt parameters list */ 17499 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 17500 if (handle_common_options(&userflags[0], &mask[0], v)) 17501 continue; 17502 17503 if (!strcasecmp(v->name, "context")) { 17504 ast_copy_string(user->context, v->value, sizeof(user->context)); 17505 } else if (!strcasecmp(v->name, "subscribecontext")) { 17506 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 17507 } else if (!strcasecmp(v->name, "setvar")) { 17508 varname = ast_strdupa(v->value); 17509 if ((varval = strchr(varname,'='))) { 17510 *varval++ = '\0'; 17511 if ((tmpvar = ast_variable_new(varname, varval))) { 17512 tmpvar->next = user->chanvars; 17513 user->chanvars = tmpvar; 17514 } 17515 } 17516 } else if (!strcasecmp(v->name, "permit") || 17517 !strcasecmp(v->name, "deny")) { 17518 user->ha = ast_append_ha(v->name, v->value, user->ha); 17519 } else if (!strcasecmp(v->name, "allowtransfer")) { 17520 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17521 } else if (!strcasecmp(v->name, "secret")) { 17522 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 17523 } else if (!strcasecmp(v->name, "md5secret")) { 17524 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 17525 } else if (!strcasecmp(v->name, "callerid")) { 17526 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 17527 } else if (!strcasecmp(v->name, "fullname")) { 17528 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 17529 } else if (!strcasecmp(v->name, "cid_number")) { 17530 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 17531 } else if (!strcasecmp(v->name, "callgroup")) { 17532 user->callgroup = ast_get_group(v->value); 17533 } else if (!strcasecmp(v->name, "pickupgroup")) { 17534 user->pickupgroup = ast_get_group(v->value); 17535 } else if (!strcasecmp(v->name, "language")) { 17536 ast_copy_string(user->language, v->value, sizeof(user->language)); 17537 } else if (!strcasecmp(v->name, "mohinterpret") 17538 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17539 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 17540 } else if (!strcasecmp(v->name, "mohsuggest")) { 17541 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 17542 } else if (!strcasecmp(v->name, "accountcode")) { 17543 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 17544 } else if (!strcasecmp(v->name, "call-limit")) { 17545 user->call_limit = atoi(v->value); 17546 if (user->call_limit < 0) 17547 user->call_limit = 0; 17548 } else if (!strcasecmp(v->name, "amaflags")) { 17549 format = ast_cdr_amaflags2int(v->value); 17550 if (format < 0) { 17551 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 17552 } else { 17553 user->amaflags = format; 17554 } 17555 } else if (!strcasecmp(v->name, "allow")) { 17556 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 17557 } else if (!strcasecmp(v->name, "disallow")) { 17558 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 17559 } else if (!strcasecmp(v->name, "autoframing")) { 17560 user->autoframing = ast_true(v->value); 17561 } else if (!strcasecmp(v->name, "callingpres")) { 17562 user->callingpres = ast_parse_caller_presentation(v->value); 17563 if (user->callingpres == -1) 17564 user->callingpres = atoi(v->value); 17565 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17566 user->maxcallbitrate = atoi(v->value); 17567 if (user->maxcallbitrate < 0) 17568 user->maxcallbitrate = default_maxcallbitrate; 17569 } 17570 /* We can't just report unknown options here because this may be a 17571 * type=friend entry. All user options are valid for a peer, but not 17572 * the other way around. */ 17573 } 17574 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 17575 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 17576 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 17577 global_allowsubscribe = TRUE; /* No global ban any more */ 17578 ast_free_ha(oldha); 17579 return user; 17580 }
static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 1824 of file chan_sip.c.
References ast_inet_ntoa(), ast_test_flag, sip_pvt::branch, sip_pvt::flags, sip_pvt::ourip, ourport, SIP_NAT, SIP_NAT_RFC3581, and sip_pvt::via.
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().
01825 { 01826 /* Work around buggy UNIDEN UIP200 firmware */ 01827 const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : ""; 01828 01829 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01830 snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s", 01831 ast_inet_ntoa(p->ourip), ourport, (int) p->branch, rport); 01832 }
static int cb_extensionstate | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 8960 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().
08961 { 08962 struct sip_pvt *p = data; 08963 08964 ast_mutex_lock(&p->lock); 08965 08966 switch(state) { 08967 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 08968 case AST_EXTENSION_REMOVED: /* Extension is gone */ 08969 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 08970 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08971 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 08972 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); 08973 p->stateid = -1; 08974 p->subscribed = NONE; 08975 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 08976 break; 08977 default: /* Tell user */ 08978 p->laststate = state; 08979 break; 08980 } 08981 if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */ 08982 if (!p->pendinginvite) { 08983 transmit_state_notify(p, state, 1, FALSE); 08984 } else { 08985 /* We already have a NOTIFY sent that is not answered. Queue the state up. 08986 if many state changes happen meanwhile, we will only send a notification of the last one */ 08987 ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 08988 } 08989 } 08990 if (option_verbose > 1) 08991 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, 08992 ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : ""); 08993 08994 08995 ast_mutex_unlock(&p->lock); 08996 08997 return 0; 08998 }
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 5158 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().
05159 { 05160 if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 05161 sip_peer_hold(dialog, holdstate); 05162 if (global_callevents) 05163 manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold", 05164 "Channel: %s\r\n" 05165 "Uniqueid: %s\r\n", 05166 dialog->owner->name, 05167 dialog->owner->uniqueid); 05168 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data); 05169 if (!holdstate) { /* Put off remote hold */ 05170 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 05171 return; 05172 } 05173 /* No address for RTP, we're on hold */ 05174 05175 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 05176 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 05177 else if (sendonly == 2) /* Inactive stream */ 05178 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 05179 else 05180 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 05181 return; 05182 }
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 8762 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_skip_blanks(), 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, set_nonce_randdata(), sip_methods, SIP_PKT_IGNORE, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stalenonce, ast_dynamic_str::str, text, transmit_response_with_auth(), and TRUE.
Referenced by check_user_full(), and register_verify().
08765 { 08766 const char *response = "407 Proxy Authentication Required"; 08767 const char *reqheader = "Proxy-Authorization"; 08768 const char *respheader = "Proxy-Authenticate"; 08769 const char *authtoken; 08770 char a1_hash[256]; 08771 char resp_hash[256]=""; 08772 char *c; 08773 int wrongnonce = FALSE; 08774 int good_response; 08775 const char *usednonce = p->randdata; 08776 struct ast_dynamic_str *buf; 08777 int res; 08778 08779 /* table of recognised keywords, and their value in the digest */ 08780 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 08781 struct x { 08782 const char *key; 08783 const char *s; 08784 } *i, keys[] = { 08785 [K_RESP] = { "response=", "" }, 08786 [K_URI] = { "uri=", "" }, 08787 [K_USER] = { "username=", "" }, 08788 [K_NONCE] = { "nonce=", "" }, 08789 [K_LAST] = { NULL, NULL} 08790 }; 08791 08792 /* Always OK if no secret */ 08793 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 08794 return AUTH_SUCCESSFUL; 08795 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 08796 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 08797 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 08798 different circumstances! What a surprise. */ 08799 response = "401 Unauthorized"; 08800 reqheader = "Authorization"; 08801 respheader = "WWW-Authenticate"; 08802 } 08803 authtoken = get_header(req, reqheader); 08804 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 08805 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 08806 information */ 08807 if (!reliable) { 08808 /* Resend message if this was NOT a reliable delivery. Otherwise the 08809 retransmission should get it */ 08810 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08811 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 08812 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08813 } 08814 return AUTH_CHALLENGE_SENT; 08815 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 08816 /* We have no auth, so issue challenge and request authentication */ 08817 set_nonce_randdata(p, 1); /* Create nonce for challenge */ 08818 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08819 /* Schedule auto destroy in 32 seconds */ 08820 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08821 return AUTH_CHALLENGE_SENT; 08822 } 08823 08824 /* --- We have auth, so check it */ 08825 08826 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 08827 an example in the spec of just what it is you're doing a hash on. */ 08828 08829 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) 08830 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08831 08832 /* Make a copy of the response and parse it */ 08833 res = ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken); 08834 08835 if (res == AST_DYNSTR_BUILD_FAILED) 08836 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08837 08838 c = buf->str; 08839 08840 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 08841 for (i = keys; i->key != NULL; i++) { 08842 const char *separator = ","; /* default */ 08843 08844 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 08845 continue; 08846 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08847 c += strlen(i->key); 08848 if (*c == '"') { /* in quotes. Skip first and look for last */ 08849 c++; 08850 separator = "\""; 08851 } 08852 i->s = c; 08853 strsep(&c, separator); 08854 break; 08855 } 08856 if (i->key == NULL) /* not found, jump after space or comma */ 08857 strsep(&c, " ,"); 08858 } 08859 08860 /* Verify that digest username matches the username we auth as */ 08861 if (strcmp(username, keys[K_USER].s)) { 08862 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 08863 username, keys[K_USER].s); 08864 /* Oops, we're trying something here */ 08865 return AUTH_USERNAME_MISMATCH; 08866 } 08867 08868 /* Verify nonce from request matches our nonce, and the nonce has not already been responded to. 08869 * If this check fails, send 401 with new nonce */ 08870 if (strcasecmp(p->randdata, keys[K_NONCE].s) || p->stalenonce) { /* XXX it was 'n'casecmp ? */ 08871 wrongnonce = TRUE; 08872 usednonce = keys[K_NONCE].s; 08873 } else { 08874 p->stalenonce = 1; /* now, since the nonce has a response, mark it as stale so it can't be sent or responded to again */ 08875 } 08876 08877 if (!ast_strlen_zero(md5secret)) 08878 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 08879 else { 08880 char a1[256]; 08881 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 08882 ast_md5_hash(a1_hash, a1); 08883 } 08884 08885 /* compute the expected response to compare with what we received */ 08886 { 08887 char a2[256]; 08888 char a2_hash[256]; 08889 char resp[256]; 08890 08891 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 08892 S_OR(keys[K_URI].s, uri)); 08893 ast_md5_hash(a2_hash, a2); 08894 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 08895 ast_md5_hash(resp_hash, resp); 08896 } 08897 08898 good_response = keys[K_RESP].s && 08899 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 08900 if (wrongnonce) { 08901 if (good_response) { 08902 if (sipdebug) 08903 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To")); 08904 /* We got working auth token, based on stale nonce . */ 08905 set_nonce_randdata(p, 0); 08906 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 08907 } else { 08908 /* Everything was wrong, so give the device one more try with a new challenge */ 08909 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 08910 if (sipdebug) 08911 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 08912 set_nonce_randdata(p, 1); 08913 } else { 08914 if (sipdebug) 08915 ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To")); 08916 } 08917 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 08918 } 08919 08920 /* Schedule auto destroy in 32 seconds */ 08921 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08922 return AUTH_CHALLENGE_SENT; 08923 } 08924 if (good_response) { 08925 append_history(p, "AuthOK", "Auth challenge succesful for %s", username); 08926 return AUTH_SUCCESSFUL; 08927 } 08928 08929 /* Ok, we have a bad username/secret pair */ 08930 /* Tell the UAS not to re-send this authentication data, because 08931 it will continue to fail 08932 */ 08933 08934 return AUTH_SECRET_FAILED; 08935 }
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 12566 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(), handle_response_invite(), and sip_reinvite_retry().
12567 { 12568 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 12569 /* if we can't BYE, then this is really a pending CANCEL */ 12570 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) 12571 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 12572 /* Actually don't destroy us yet, wait for the 487 on our original 12573 INVITE, but do set an autodestruct just in case we never get it. */ 12574 else { 12575 /* We have a pending outbound invite, don't send someting 12576 new in-transaction */ 12577 if (p->pendinginvite) 12578 return; 12579 12580 /* Perhaps there is an SD change INVITE outstanding */ 12581 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 12582 } 12583 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 12584 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12585 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 12586 /* if we can't REINVITE, hold it for later */ 12587 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 12588 if (option_debug) 12589 ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 12590 } else { 12591 if (option_debug) 12592 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 12593 /* Didn't get to reinvite yet, so do it now */ 12594 transmit_reinvite_with_sdp(p); 12595 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 12596 } 12597 } 12598 }
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 17346 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().
17347 { 17348 struct domain *d; 17349 int result = 0; 17350 17351 AST_LIST_LOCK(&domain_list); 17352 AST_LIST_TRAVERSE(&domain_list, d, list) { 17353 if (strcasecmp(d->domain, domain)) 17354 continue; 17355 17356 if (len && !ast_strlen_zero(d->context)) 17357 ast_copy_string(context, d->context, len); 17358 17359 result = 1; 17360 break; 17361 } 17362 AST_LIST_UNLOCK(&domain_list); 17363 17364 return result; 17365 }
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 10181 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
10182 { 10183 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 10184 }
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 9852 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_RPORT_PRESENT, 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().
09855 { 09856 struct sip_user *user = NULL; 09857 struct sip_peer *peer; 09858 char from[256], *c; 09859 char *of; 09860 char rpid_num[50]; 09861 const char *rpid; 09862 enum check_auth_result res = AUTH_SUCCESSFUL; 09863 char *t; 09864 char calleridname[50]; 09865 int debug=sip_debug_test_addr(sin); 09866 struct ast_variable *tmpvar = NULL, *v = NULL; 09867 char *uri2 = ast_strdupa(uri); 09868 09869 /* Terminate URI */ 09870 t = uri2; 09871 while (*t && *t > 32 && *t != ';') 09872 t++; 09873 *t = '\0'; 09874 ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */ 09875 if (pedanticsipchecking) 09876 ast_uri_decode(from); 09877 /* XXX here tries to map the username for invite things */ 09878 memset(calleridname, 0, sizeof(calleridname)); 09879 get_calleridname(from, calleridname, sizeof(calleridname)); 09880 if (calleridname[0]) 09881 ast_string_field_set(p, cid_name, calleridname); 09882 09883 rpid = get_header(req, "Remote-Party-ID"); 09884 memset(rpid_num, 0, sizeof(rpid_num)); 09885 if (!ast_strlen_zero(rpid)) 09886 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 09887 09888 of = get_in_brackets(from); 09889 if (ast_strlen_zero(p->exten)) { 09890 t = uri2; 09891 if (!strncasecmp(t, "sip:", 4)) 09892 t+= 4; 09893 ast_string_field_set(p, exten, t); 09894 t = strchr(p->exten, '@'); 09895 if (t) 09896 *t = '\0'; 09897 if (ast_strlen_zero(p->our_contact)) 09898 build_contact(p); 09899 } 09900 /* save the URI part of the From header */ 09901 ast_string_field_set(p, from, of); 09902 if (strncasecmp(of, "sip:", 4)) { 09903 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 09904 } else 09905 of += 4; 09906 /* Get just the username part */ 09907 if ((c = strchr(of, '@'))) { 09908 char *tmp; 09909 *c = '\0'; 09910 if ((c = strchr(of, ':'))) 09911 *c = '\0'; 09912 tmp = ast_strdupa(of); 09913 /* We need to be able to handle auth-headers looking like 09914 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 09915 */ 09916 tmp = strsep(&tmp, ";"); 09917 if (ast_is_shrinkable_phonenumber(tmp)) 09918 ast_shrink_phone_number(tmp); 09919 ast_string_field_set(p, cid_num, tmp); 09920 } 09921 09922 if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */ 09923 user = find_user(of, 1); 09924 09925 /* Find user based on user name in the from header */ 09926 if (user && ast_apply_ha(user->ha, sin)) { 09927 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09928 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09929 if (sipmethod == SIP_INVITE) { 09930 /* copy channel vars */ 09931 for (v = user->chanvars ; v ; v = v->next) { 09932 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09933 tmpvar->next = p->chanvars; 09934 p->chanvars = tmpvar; 09935 } 09936 } 09937 } 09938 p->prefs = user->prefs; 09939 /* Set Frame packetization */ 09940 if (p->rtp) { 09941 ast_rtp_codec_setpref(p->rtp, &p->prefs); 09942 p->autoframing = user->autoframing; 09943 } 09944 /* replace callerid if rpid found, and not restricted */ 09945 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09946 char *tmp; 09947 if (*calleridname) 09948 ast_string_field_set(p, cid_name, calleridname); 09949 tmp = ast_strdupa(rpid_num); 09950 if (ast_is_shrinkable_phonenumber(tmp)) 09951 ast_shrink_phone_number(tmp); 09952 ast_string_field_set(p, cid_num, tmp); 09953 } 09954 09955 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 09956 09957 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09958 if (sip_cancel_destroy(p)) 09959 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09960 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09961 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09962 /* Copy SIP extensions profile from INVITE */ 09963 if (p->sipoptions) 09964 user->sipoptions = p->sipoptions; 09965 09966 /* If we have a call limit, set flag */ 09967 if (user->call_limit) 09968 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09969 if (!ast_strlen_zero(user->context)) 09970 ast_string_field_set(p, context, user->context); 09971 if (!ast_strlen_zero(user->cid_num)) { 09972 char *tmp = ast_strdupa(user->cid_num); 09973 if (ast_is_shrinkable_phonenumber(tmp)) 09974 ast_shrink_phone_number(tmp); 09975 ast_string_field_set(p, cid_num, tmp); 09976 } 09977 if (!ast_strlen_zero(user->cid_name)) 09978 ast_string_field_set(p, cid_name, user->cid_name); 09979 ast_string_field_set(p, username, user->name); 09980 ast_string_field_set(p, peername, user->name); 09981 ast_string_field_set(p, peersecret, user->secret); 09982 ast_string_field_set(p, peermd5secret, user->md5secret); 09983 ast_string_field_set(p, subscribecontext, user->subscribecontext); 09984 ast_string_field_set(p, accountcode, user->accountcode); 09985 ast_string_field_set(p, language, user->language); 09986 ast_string_field_set(p, mohsuggest, user->mohsuggest); 09987 ast_string_field_set(p, mohinterpret, user->mohinterpret); 09988 p->allowtransfer = user->allowtransfer; 09989 p->amaflags = user->amaflags; 09990 p->callgroup = user->callgroup; 09991 p->pickupgroup = user->pickupgroup; 09992 if (user->callingpres) /* User callingpres setting will override RPID header */ 09993 p->callingpres = user->callingpres; 09994 09995 /* Set default codec settings for this call */ 09996 p->capability = user->capability; /* User codec choice */ 09997 p->jointcapability = user->capability; /* Our codecs */ 09998 if (p->peercapability) /* AND with peer's codecs */ 09999 p->jointcapability &= p->peercapability; 10000 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 10001 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 10002 p->noncodeccapability |= AST_RTP_DTMF; 10003 else 10004 p->noncodeccapability &= ~AST_RTP_DTMF; 10005 p->jointnoncodeccapability = p->noncodeccapability; 10006 if (p->t38.peercapability) 10007 p->t38.jointcapability &= p->t38.peercapability; 10008 p->maxcallbitrate = user->maxcallbitrate; 10009 /* If we do not support video, remove video from call structure */ 10010 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 10011 ast_rtp_destroy(p->vrtp); 10012 p->vrtp = NULL; 10013 } 10014 } 10015 if (user && debug) 10016 ast_verbose("Found user '%s'\n", user->name); 10017 } else { 10018 if (user) { 10019 if (!authpeer && debug) 10020 ast_verbose("Found user '%s', but fails host access\n", user->name); 10021 ASTOBJ_UNREF(user,sip_destroy_user); 10022 } 10023 user = NULL; 10024 } 10025 10026 if (!user) { 10027 /* If we didn't find a user match, check for peers */ 10028 if (sipmethod == SIP_SUBSCRIBE) 10029 /* For subscribes, match on peer name only */ 10030 peer = find_peer(of, NULL, 1, 0); 10031 else 10032 /* Look for peer based on the IP address we received data from */ 10033 /* If peer is registered from this IP address or have this as a default 10034 IP address, this call is from the peer 10035 */ 10036 peer = find_peer(NULL, &p->recv, 1, 0); 10037 10038 if (peer) { 10039 /* Set Frame packetization */ 10040 if (p->rtp) { 10041 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 10042 p->autoframing = peer->autoframing; 10043 } 10044 if (debug) 10045 ast_verbose("Found peer '%s'\n", peer->name); 10046 10047 /* Take the peer */ 10048 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 10049 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 10050 10051 /* Copy SIP extensions profile to peer */ 10052 if (p->sipoptions) 10053 peer->sipoptions = p->sipoptions; 10054 10055 /* replace callerid if rpid found, and not restricted */ 10056 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 10057 char *tmp = ast_strdupa(rpid_num); 10058 if (*calleridname) 10059 ast_string_field_set(p, cid_name, calleridname); 10060 if (ast_is_shrinkable_phonenumber(tmp)) 10061 ast_shrink_phone_number(tmp); 10062 ast_string_field_set(p, cid_num, tmp); 10063 } 10064 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 10065 10066 ast_string_field_set(p, peersecret, peer->secret); 10067 ast_string_field_set(p, peermd5secret, peer->md5secret); 10068 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 10069 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 10070 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 10071 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 10072 p->callingpres = peer->callingpres; 10073 if (peer->maxms && peer->lastms) 10074 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 10075 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 10076 /* Pretend there is no required authentication */ 10077 ast_string_field_free(p, peersecret); 10078 ast_string_field_free(p, peermd5secret); 10079 } 10080 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 10081 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 10082 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 10083 /* If we have a call limit, set flag */ 10084 if (peer->call_limit) 10085 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 10086 ast_string_field_set(p, peername, peer->name); 10087 ast_string_field_set(p, authname, peer->name); 10088 10089 if (sipmethod == SIP_INVITE) { 10090 /* copy channel vars */ 10091 for (v = peer->chanvars ; v ; v = v->next) { 10092 if ((tmpvar = ast_variable_new(v->name, v->value))) { 10093 tmpvar->next = p->chanvars; 10094 p->chanvars = tmpvar; 10095 } 10096 } 10097 } 10098 if (authpeer) { 10099 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 10100 } 10101 10102 if (!ast_strlen_zero(peer->username)) { 10103 ast_string_field_set(p, username, peer->username); 10104 /* Use the default username for authentication on outbound calls */ 10105 /* XXX this takes the name from the caller... can we override ? */ 10106 ast_string_field_set(p, authname, peer->username); 10107 } 10108 if (!ast_strlen_zero(peer->cid_num)) { 10109 char *tmp = ast_strdupa(peer->cid_num); 10110 if (ast_is_shrinkable_phonenumber(tmp)) 10111 ast_shrink_phone_number(tmp); 10112 ast_string_field_set(p, cid_num, tmp); 10113 } 10114 if (!ast_strlen_zero(peer->cid_name)) 10115 ast_string_field_set(p, cid_name, peer->cid_name); 10116 ast_string_field_set(p, fullcontact, peer->fullcontact); 10117 if (!ast_strlen_zero(peer->context)) 10118 ast_string_field_set(p, context, peer->context); 10119 ast_string_field_set(p, peersecret, peer->secret); 10120 ast_string_field_set(p, peermd5secret, peer->md5secret); 10121 ast_string_field_set(p, language, peer->language); 10122 ast_string_field_set(p, accountcode, peer->accountcode); 10123 p->amaflags = peer->amaflags; 10124 p->callgroup = peer->callgroup; 10125 p->pickupgroup = peer->pickupgroup; 10126 p->capability = peer->capability; 10127 p->prefs = peer->prefs; 10128 p->jointcapability = peer->capability; 10129 if (p->peercapability) 10130 p->jointcapability &= p->peercapability; 10131 p->maxcallbitrate = peer->maxcallbitrate; 10132 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 10133 ast_rtp_destroy(p->vrtp); 10134 p->vrtp = NULL; 10135 } 10136 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 10137 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 10138 p->noncodeccapability |= AST_RTP_DTMF; 10139 else 10140 p->noncodeccapability &= ~AST_RTP_DTMF; 10141 p->jointnoncodeccapability = p->noncodeccapability; 10142 if (p->t38.peercapability) 10143 p->t38.jointcapability &= p->t38.peercapability; 10144 } 10145 ASTOBJ_UNREF(peer, sip_destroy_peer); 10146 } else { 10147 if (debug) 10148 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 10149 10150 /* do we allow guests? */ 10151 if (!global_allowguest) { 10152 if (global_alwaysauthreject) 10153 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 10154 else 10155 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 10156 } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 10157 char *tmp = ast_strdupa(rpid_num); 10158 if (*calleridname) 10159 ast_string_field_set(p, cid_name, calleridname); 10160 if (ast_is_shrinkable_phonenumber(tmp)) 10161 ast_shrink_phone_number(tmp); 10162 ast_string_field_set(p, cid_num, tmp); 10163 } 10164 } 10165 10166 } 10167 10168 if (user) 10169 ASTOBJ_UNREF(user, sip_destroy_user); 10170 10171 if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT)) { 10172 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 10173 } 10174 10175 return res; 10176 }
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 9720 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_PAGE2_RPORT_PRESENT, 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().
09721 { 09722 char via[512]; 09723 char *c, *pt; 09724 struct hostent *hp; 09725 struct ast_hostent ahp; 09726 09727 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 09728 09729 /* Work on the leftmost value of the topmost Via header */ 09730 c = strchr(via, ','); 09731 if (c) 09732 *c = '\0'; 09733 09734 /* Check for rport */ 09735 c = strstr(via, ";rport"); 09736 if (c && (c[6] != '=')) /* rport query, not answer */ 09737 ast_set_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT); 09738 09739 c = strchr(via, ';'); 09740 if (c) 09741 *c = '\0'; 09742 09743 c = strchr(via, ' '); 09744 if (c) { 09745 *c = '\0'; 09746 c = ast_skip_blanks(c+1); 09747 if (strcasecmp(via, "SIP/2.0/UDP")) { 09748 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 09749 return; 09750 } 09751 pt = strchr(c, ':'); 09752 if (pt) 09753 *pt++ = '\0'; /* remember port pointer */ 09754 hp = ast_gethostbyname(c, &ahp); 09755 if (!hp) { 09756 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 09757 return; 09758 } 09759 memset(&p->sa, 0, sizeof(p->sa)); 09760 p->sa.sin_family = AF_INET; 09761 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 09762 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 09763 09764 if (sip_debug_test_pvt(p)) { 09765 const struct sockaddr_in *dst = sip_real_dst(p); 09766 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 09767 } 09768 } 09769 }
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 10625 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), ast_copy_string(), and AST_MAX_CONTEXT.
10626 { 10627 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 10628 10629 while ((oldcontext = strsep(&old, "&"))) { 10630 stalecontext = '\0'; 10631 ast_copy_string(newlist, new, sizeof(newlist)); 10632 stringp = newlist; 10633 while ((newcontext = strsep(&stringp, "&"))) { 10634 if (strcmp(newcontext, oldcontext) == 0) { 10635 /* This is not the context you're looking for */ 10636 stalecontext = '\0'; 10637 break; 10638 } else if (strcmp(newcontext, oldcontext)) { 10639 stalecontext = oldcontext; 10640 } 10641 10642 } 10643 if (stalecontext) 10644 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 10645 } 10646 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 17439 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().
17440 { 17441 struct sip_auth *a = authlist; 17442 struct sip_auth *b; 17443 17444 while (a) { 17445 b = a; 17446 a = a->next; 17447 free(b); 17448 } 17449 17450 return 1; 17451 }
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 17368 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().
17369 { 17370 struct domain *d; 17371 17372 AST_LIST_LOCK(&domain_list); 17373 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 17374 free(d); 17375 AST_LIST_UNLOCK(&domain_list); 17376 }
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 11444 of file chan_sip.c.
References complete_sip_peer().
11445 { 11446 if (pos == 3) 11447 return complete_sip_peer(word, state, 0); 11448 11449 return NULL; 11450 }
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 11418 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().
11419 { 11420 char *result = NULL; 11421 int wordlen = strlen(word); 11422 int which = 0; 11423 11424 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 11425 /* locking of the object is not required because only the name and flags are being compared */ 11426 if (!strncasecmp(word, iterator->name, wordlen) && 11427 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 11428 ++which > state) 11429 result = ast_strdup(iterator->name); 11430 } while(0) ); 11431 return result; 11432 }
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 11512 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
11513 { 11514 if (pos == 4) 11515 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11516 return NULL; 11517 }
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 11520 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
11521 { 11522 if (pos == 4) 11523 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11524 11525 return NULL; 11526 }
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 11435 of file chan_sip.c.
References complete_sip_peer().
11436 { 11437 if (pos == 3) 11438 return complete_sip_peer(word, state, 0); 11439 11440 return NULL; 11441 }
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 11473 of file chan_sip.c.
References complete_sip_user().
11474 { 11475 if (pos == 3) 11476 return complete_sip_user(word, state, 0); 11477 11478 return NULL; 11479 }
static char * complete_sip_user | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on user name.
Definition at line 11453 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().
11454 { 11455 char *result = NULL; 11456 int wordlen = strlen(word); 11457 int which = 0; 11458 11459 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 11460 /* locking of the object is not required because only the name and flags are being compared */ 11461 if (!strncasecmp(word, iterator->name, wordlen)) { 11462 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 11463 continue; 11464 if (++which > state) { 11465 result = ast_strdup(iterator->name); 11466 } 11467 } 11468 } while(0) ); 11469 return result; 11470 }
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 11395 of file chan_sip.c.
References ast_mutex_lock, ast_strdup, sip_pvt::callid, iflist, iflock, and sip_pvt::next.
11396 { 11397 int which=0; 11398 struct sip_pvt *cur; 11399 char *c = NULL; 11400 int wordlen = strlen(word); 11401 11402 if (pos != 3) { 11403 return NULL; 11404 } 11405 11406 ast_mutex_lock(&iflock); 11407 for (cur = iflist; cur; cur = cur->next) { 11408 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 11409 c = ast_strdup(cur->callid); 11410 break; 11411 } 11412 } 11413 ast_mutex_unlock(&iflock); 11414 return c; 11415 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 11482 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
11483 { 11484 char *c = NULL; 11485 11486 if (pos == 2) { 11487 int which = 0; 11488 char *cat = NULL; 11489 int wordlen = strlen(word); 11490 11491 /* do completion for notify type */ 11492 11493 if (!notify_types) 11494 return NULL; 11495 11496 while ( (cat = ast_category_browse(notify_types, cat)) ) { 11497 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 11498 c = ast_strdup(cat); 11499 break; 11500 } 11501 } 11502 return c; 11503 } 11504 11505 if (pos > 2) 11506 return complete_sip_peer(word, state, 0); 11507 11508 return NULL; 11509 }
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 5940 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
05941 { 05942 int start = 0; 05943 int copied = 0; 05944 for (;;) { 05945 const char *tmp = __get_header(orig, field, &start); 05946 05947 if (ast_strlen_zero(tmp)) 05948 break; 05949 /* Add what we're responding to */ 05950 add_header(req, field, tmp); 05951 copied++; 05952 } 05953 return copied ? 0 : -1; 05954 }
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 5929 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
05930 { 05931 const char *tmp = get_header(orig, field); 05932 05933 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 05934 return add_header(req, field, tmp); 05935 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 05936 return -1; 05937 }
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 7008 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().
07009 { 07010 long offset; 07011 int x; 07012 offset = ((void *)dst) - ((void *)src); 07013 /* First copy stuff */ 07014 memcpy(dst, src, sizeof(*dst)); 07015 /* Now fix pointer arithmetic */ 07016 for (x=0; x < src->headers; x++) 07017 dst->header[x] += offset; 07018 for (x=0; x < src->lines; x++) 07019 dst->line[x] += offset; 07020 dst->rlPart1 += offset; 07021 dst->rlPart2 += offset; 07022 }
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 5962 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().
05963 { 05964 int copied = 0; 05965 int start = 0; 05966 05967 for (;;) { 05968 char new[512]; 05969 const char *oh = __get_header(orig, field, &start); 05970 05971 if (ast_strlen_zero(oh)) 05972 break; 05973 05974 if (!copied) { /* Only check for empty rport in topmost via header */ 05975 char leftmost[512], *others, *rport; 05976 05977 /* Only work on leftmost value */ 05978 ast_copy_string(leftmost, oh, sizeof(leftmost)); 05979 others = strchr(leftmost, ','); 05980 if (others) 05981 *others++ = '\0'; 05982 05983 /* Find ;rport; (empty request) */ 05984 rport = strstr(leftmost, ";rport"); 05985 if (rport && *(rport+6) == '=') 05986 rport = NULL; /* We already have a parameter to rport */ 05987 05988 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 05989 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 05990 /* We need to add received port - rport */ 05991 char *end; 05992 05993 rport = strstr(leftmost, ";rport"); 05994 05995 if (rport) { 05996 end = strchr(rport + 1, ';'); 05997 if (end) 05998 memmove(rport, end, strlen(end) + 1); 05999 else 06000 *rport = '\0'; 06001 } 06002 06003 /* Add rport to first VIA header if requested */ 06004 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 06005 leftmost, ast_inet_ntoa(p->recv.sin_addr), 06006 ntohs(p->recv.sin_port), 06007 others ? "," : "", others ? others : ""); 06008 } else { 06009 /* We should *always* add a received to the topmost via */ 06010 snprintf(new, sizeof(new), "%s;received=%s%s%s", 06011 leftmost, ast_inet_ntoa(p->recv.sin_addr), 06012 others ? "," : "", others ? others : ""); 06013 } 06014 oh = new; /* the header to copy */ 06015 } /* else add the following via headers untouched */ 06016 add_header(req, field, oh); 06017 copied++; 06018 } 06019 if (!copied) { 06020 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 06021 return -1; 06022 } 06023 return 0; 06024 }
static int create_addr | ( | struct sip_pvt * | dialog, | |
const char * | opeer, | |||
struct sockaddr_in * | sin | |||
) | [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 2942 of file chan_sip.c.
References ahp, ast_copy_string(), ast_get_srv(), ast_gethostbyname(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ASTOBJ_UNREF, create_addr_from_peer(), do_setnat(), find_peer(), sip_pvt::flags, hp, portno, sip_pvt::recv, sip_pvt::sa, sip_destroy_peer(), SIP_NAT, SIP_NAT_ROUTE, STANDARD_SIP_PORT, sip_pvt::timer_t1, and sip_peer::tohost.
02943 { 02944 struct hostent *hp; 02945 struct ast_hostent ahp; 02946 struct sip_peer *p; 02947 char *port; 02948 int portno = 0; 02949 char host[MAXHOSTNAMELEN], *hostn; 02950 char peer[256]; 02951 02952 ast_copy_string(peer, opeer, sizeof(peer)); 02953 port = strchr(peer, ':'); 02954 if (port) 02955 *port++ = '\0'; 02956 dialog->sa.sin_family = AF_INET; 02957 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 02958 p = find_peer(peer, NULL, 1, 0); 02959 02960 if (p) { 02961 int res = create_addr_from_peer(dialog, p); 02962 if (port) { 02963 portno = atoi(port); 02964 dialog->sa.sin_port = dialog->recv.sin_port = htons(portno); 02965 } 02966 ASTOBJ_UNREF(p, sip_destroy_peer); 02967 return res; 02968 } 02969 02970 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 02971 02972 ast_string_field_set(dialog, tohost, peer); 02973 02974 if (sin) { 02975 memcpy(&dialog->sa.sin_addr, &sin->sin_addr, sizeof(dialog->sa.sin_addr)); 02976 if (!sin->sin_port) { 02977 if (ast_strlen_zero(port) || sscanf(port, "%30u", &portno) != 1) { 02978 portno = STANDARD_SIP_PORT; 02979 } 02980 } else { 02981 portno = ntohs(sin->sin_port); 02982 } 02983 } else { 02984 hostn = peer; 02985 /* Section 4.2 of RFC 3263 specifies that if a port number is specified, then 02986 * an A record lookup should be used instead of SRV. 02987 */ 02988 if (!port && srvlookup) { 02989 char service[MAXHOSTNAMELEN]; 02990 int tportno; 02991 int ret; 02992 02993 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 02994 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 02995 if (ret > 0) { 02996 hostn = host; 02997 portno = tportno; 02998 } 02999 } 03000 if (!portno) 03001 portno = port ? atoi(port) : STANDARD_SIP_PORT; 03002 03003 hp = ast_gethostbyname(hostn, &ahp); 03004 if (!hp) { 03005 ast_log(LOG_WARNING, "No such host: %s\n", peer); 03006 return -1; 03007 } 03008 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 03009 } 03010 dialog->sa.sin_port = htons(portno); 03011 dialog->recv = dialog->sa; 03012 return 0; 03013 }
Create address structure from peer reference. return -1 on error, 0 on success.
Definition at line 2833 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_VIDEOSUPPORT, sip_pvt::t38, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, sip_pvt::timer_t1, sip_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().
02834 { 02835 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 02836 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 02837 dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr; 02838 dialog->recv = dialog->sa; 02839 } else 02840 return -1; 02841 02842 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 02843 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 02844 dialog->capability = peer->capability; 02845 if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) { 02846 ast_rtp_destroy(dialog->vrtp); 02847 dialog->vrtp = NULL; 02848 } 02849 dialog->prefs = peer->prefs; 02850 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) { 02851 dialog->t38.capability = global_t38_capability; 02852 if (dialog->udptl) { 02853 if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC ) 02854 dialog->t38.capability |= T38FAX_UDP_EC_FEC; 02855 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY ) 02856 dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 02857 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE ) 02858 dialog->t38.capability |= T38FAX_UDP_EC_NONE; 02859 dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 02860 if (option_debug > 1) 02861 ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability); 02862 } 02863 dialog->t38.jointcapability = dialog->t38.capability; 02864 } else if (dialog->udptl) { 02865 ast_udptl_destroy(dialog->udptl); 02866 dialog->udptl = NULL; 02867 } 02868 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE ); 02869 02870 if (dialog->rtp) { 02871 ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 02872 ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 02873 ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); 02874 ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); 02875 ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); 02876 /* Set Frame packetization */ 02877 ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); 02878 dialog->autoframing = peer->autoframing; 02879 } 02880 if (dialog->vrtp) { 02881 ast_rtp_setdtmf(dialog->vrtp, 0); 02882 ast_rtp_setdtmfcompensate(dialog->vrtp, 0); 02883 ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); 02884 ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); 02885 ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); 02886 } 02887 02888 ast_string_field_set(dialog, peername, peer->name); 02889 ast_string_field_set(dialog, authname, peer->username); 02890 ast_string_field_set(dialog, username, peer->username); 02891 ast_string_field_set(dialog, peersecret, peer->secret); 02892 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 02893 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 02894 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 02895 ast_string_field_set(dialog, tohost, peer->tohost); 02896 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 02897 if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 02898 char *tmpcall; 02899 char *c; 02900 tmpcall = ast_strdupa(dialog->callid); 02901 c = strchr(tmpcall, '@'); 02902 if (c) { 02903 *c = '\0'; 02904 ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain); 02905 } 02906 } 02907 if (ast_strlen_zero(dialog->tohost)) 02908 ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr)); 02909 if (!ast_strlen_zero(peer->fromdomain)) 02910 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 02911 if (!ast_strlen_zero(peer->fromuser)) 02912 ast_string_field_set(dialog, fromuser, peer->fromuser); 02913 if (!ast_strlen_zero(peer->language)) 02914 ast_string_field_set(dialog, language, peer->language); 02915 dialog->maxtime = peer->maxms; 02916 dialog->callgroup = peer->callgroup; 02917 dialog->pickupgroup = peer->pickupgroup; 02918 dialog->peerauth = peer->auth; 02919 dialog->allowtransfer = peer->allowtransfer; 02920 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 02921 /* Minimum is settable or default to 100 ms */ 02922 if (peer->maxms && peer->lastms) 02923 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 02924 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 02925 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 02926 dialog->noncodeccapability |= AST_RTP_DTMF; 02927 else 02928 dialog->noncodeccapability &= ~AST_RTP_DTMF; 02929 dialog->jointnoncodeccapability = dialog->noncodeccapability; 02930 ast_string_field_set(dialog, context, peer->context); 02931 dialog->rtptimeout = peer->rtptimeout; 02932 if (peer->call_limit) 02933 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 02934 dialog->maxcallbitrate = peer->maxcallbitrate; 02935 02936 return 0; 02937 }
static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 8221 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, SIP_PAGE2_RT_FROMCONTACT, and SIP_PAGE2_RTUPDATE.
Referenced by build_peer(), expire_register(), and parse_register_contact().
08222 { 08223 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 08224 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT) && ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE)) { 08225 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL); 08226 ast_update_realtime("sippeers", "name", peer->name, "lastms", "", NULL); 08227 } else 08228 ast_db_del("SIP/Registry", peer->name); 08229 } 08230 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 7057 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().
07058 { 07059 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 07060 07061 if (!*e) 07062 return -1; 07063 req->rlPart1 = e; /* method or protocol */ 07064 e = ast_skip_nonblanks(e); 07065 if (*e) 07066 *e++ = '\0'; 07067 /* Get URI or status code */ 07068 e = ast_skip_blanks(e); 07069 if ( !*e ) 07070 return -1; 07071 ast_trim_blanks(e); 07072 07073 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 07074 if (strlen(e) < 3) /* status code is 3 digits */ 07075 return -1; 07076 req->rlPart2 = e; 07077 } else { /* We have a request */ 07078 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 07079 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 07080 e++; 07081 if (!*e) 07082 return -1; 07083 } 07084 req->rlPart2 = e; /* URI */ 07085 e = ast_skip_nonblanks(e); 07086 if (*e) 07087 *e++ = '\0'; 07088 e = ast_skip_blanks(e); 07089 if (strcasecmp(e, "SIP/2.0") ) { 07090 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 07091 return -1; 07092 } 07093 } 07094 return 1; 07095 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 16643 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_PAGE2_CALL_ONHOLD, sip_reload_lock, sipsock, sipsock_read(), t, T38_ENABLED, and VERBOSE_PREFIX_1.
16644 { 16645 int res; 16646 struct sip_pvt *sip; 16647 struct sip_peer *peer = NULL; 16648 time_t t; 16649 int fastrestart = FALSE; 16650 int lastpeernum = -1; 16651 int curpeernum; 16652 int reloading; 16653 16654 /* Add an I/O event to our SIP UDP socket */ 16655 if (sipsock > -1) 16656 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 16657 16658 /* From here on out, we die whenever asked */ 16659 for(;;) { 16660 /* Check for a reload request */ 16661 ast_mutex_lock(&sip_reload_lock); 16662 reloading = sip_reloading; 16663 sip_reloading = FALSE; 16664 ast_mutex_unlock(&sip_reload_lock); 16665 if (reloading) { 16666 if (option_verbose > 0) 16667 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 16668 sip_do_reload(sip_reloadreason); 16669 16670 /* Change the I/O fd of our UDP socket */ 16671 if (sipsock > -1) { 16672 if (sipsock_read_id) 16673 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 16674 else 16675 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 16676 } else if (sipsock_read_id) { 16677 ast_io_remove(io, sipsock_read_id); 16678 sipsock_read_id = NULL; 16679 } 16680 } 16681 restartsearch: 16682 /* Check for interfaces needing to be killed */ 16683 ast_mutex_lock(&iflock); 16684 t = time(NULL); 16685 /* don't scan the interface list if it hasn't been a reasonable period 16686 of time since the last time we did it (when MWI is being sent, we can 16687 get back to this point every millisecond or less) 16688 */ 16689 for (sip = iflist; !fastrestart && sip; sip = sip->next) { 16690 /*! \note If we can't get a lock on an interface, skip it and come 16691 * back later. Note that there is the possibility of a deadlock with 16692 * sip_hangup otherwise, because sip_hangup is called with the channel 16693 * locked first, and the iface lock is attempted second. 16694 */ 16695 if (ast_mutex_trylock(&sip->lock)) 16696 continue; 16697 16698 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 16699 if (sip->rtp && sip->owner && 16700 (sip->owner->_state == AST_STATE_UP) && 16701 !sip->redirip.sin_addr.s_addr && 16702 sip->t38.state != T38_ENABLED) { 16703 if (sip->lastrtptx && 16704 ast_rtp_get_rtpkeepalive(sip->rtp) && 16705 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) { 16706 /* Need to send an empty RTP packet */ 16707 sip->lastrtptx = time(NULL); 16708 ast_rtp_sendcng(sip->rtp, 0); 16709 } 16710 if (sip->lastrtprx && 16711 (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) && 16712 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) { 16713 /* Might be a timeout now -- see if we're on hold */ 16714 struct sockaddr_in sin; 16715 ast_rtp_get_peer(sip->rtp, &sin); 16716 if (!ast_test_flag(&sip->flags[1], SIP_PAGE2_CALL_ONHOLD) || 16717 (ast_rtp_get_rtpholdtimeout(sip->rtp) && 16718 (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) { 16719 /* Needs a hangup */ 16720 if (ast_rtp_get_rtptimeout(sip->rtp)) { 16721 while (sip->owner && ast_channel_trylock(sip->owner)) { 16722 DEADLOCK_AVOIDANCE(&sip->lock); 16723 } 16724 if (sip->owner) { 16725 ast_log(LOG_NOTICE, 16726 "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 16727 sip->owner->name, 16728 (long) (t - sip->lastrtprx)); 16729 /* Issue a softhangup */ 16730 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 16731 ast_channel_unlock(sip->owner); 16732 /* forget the timeouts for this call, since a hangup 16733 has already been requested and we don't want to 16734 repeatedly request hangups 16735 */ 16736 ast_rtp_set_rtptimeout(sip->rtp, 0); 16737 ast_rtp_set_rtpholdtimeout(sip->rtp, 0); 16738 if (sip->vrtp) { 16739 ast_rtp_set_rtptimeout(sip->vrtp, 0); 16740 ast_rtp_set_rtpholdtimeout(sip->vrtp, 0); 16741 } 16742 } 16743 } 16744 } 16745 } 16746 } 16747 /* If we have sessions that needs to be destroyed, do it now */ 16748 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && 16749 !sip->owner) { 16750 ast_mutex_unlock(&sip->lock); 16751 __sip_destroy(sip, 1); 16752 ast_mutex_unlock(&iflock); 16753 usleep(1); 16754 goto restartsearch; 16755 } 16756 ast_mutex_unlock(&sip->lock); 16757 } 16758 ast_mutex_unlock(&iflock); 16759 16760 /* XXX TODO The scheduler usage in this module does not have sufficient 16761 * synchronization being done between running the scheduler and places 16762 * scheduling tasks. As it is written, any scheduled item may not run 16763 * any sooner than about 1 second, regardless of whether a sooner time 16764 * was asked for. */ 16765 16766 pthread_testcancel(); 16767 /* Wait for sched or io */ 16768 res = ast_sched_wait(sched); 16769 if ((res < 0) || (res > 1000)) 16770 res = 1000; 16771 /* If we might need to send more mailboxes, don't wait long at all.*/ 16772 if (fastrestart) 16773 res = 1; 16774 res = ast_io_wait(io, res); 16775 if (option_debug && res > 20) 16776 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 16777 ast_mutex_lock(&monlock); 16778 res = ast_sched_runq(sched); 16779 if (option_debug && res >= 20) 16780 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 16781 16782 /* Send MWI notifications to peers - static and cached realtime peers */ 16783 t = time(NULL); 16784 fastrestart = FALSE; 16785 curpeernum = 0; 16786 peer = NULL; 16787 /* Find next peer that needs mwi */ 16788 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 16789 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 16790 fastrestart = TRUE; 16791 lastpeernum = curpeernum; 16792 peer = ASTOBJ_REF(iterator); 16793 }; 16794 curpeernum++; 16795 } while (0) 16796 ); 16797 /* Send MWI to the peer */ 16798 if (peer) { 16799 ASTOBJ_WRLOCK(peer); 16800 sip_send_mwi_to_peer(peer, FALSE); 16801 ASTOBJ_UNLOCK(peer); 16802 ASTOBJ_UNREF(peer,sip_destroy_peer); 16803 } else { 16804 /* Reset where we come from */ 16805 lastpeernum = -1; 16806 } 16807 ast_mutex_unlock(&monlock); 16808 } 16809 /* Never reached */ 16810 return NULL; 16811 16812 }
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 11992 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().
11993 { 11994 char digest[1024]; 11995 11996 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 11997 return -2; 11998 11999 p->authtries++; 12000 if (option_debug > 1) 12001 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 12002 memset(digest, 0, sizeof(digest)); 12003 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 12004 /* No way to authenticate */ 12005 return -1; 12006 } 12007 /* Now we have a reply digest */ 12008 p->options->auth = digest; 12009 p->options->authheader = respheader; 12010 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 12011 }
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 11971 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().
11972 { 11973 char digest[1024]; 11974 p->authtries++; 11975 memset(digest,0,sizeof(digest)); 11976 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 11977 /* There's nothing to use for authentication */ 11978 /* No digest challenge in request */ 11979 if (sip_debug_test_pvt(p) && p->registry) 11980 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 11981 /* No old challenge */ 11982 return -1; 11983 } 11984 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 11985 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 11986 if (sip_debug_test_pvt(p) && p->registry) 11987 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 11988 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 11989 }
static void do_setnat | ( | struct sip_pvt * | p, | |
int | natflags | |||
) | [static] |
Set nat mode on the various data sockets.
Definition at line 2809 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(), create_addr_from_peer(), sip_alloc(), and transmit_response_using_temp().
02810 { 02811 const char *mode = natflags ? "On" : "Off"; 02812 02813 if (p->rtp) { 02814 if (option_debug) 02815 ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode); 02816 ast_rtp_setnat(p->rtp, natflags); 02817 } 02818 if (p->vrtp) { 02819 if (option_debug) 02820 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode); 02821 ast_rtp_setnat(p->vrtp, natflags); 02822 } 02823 if (p->udptl) { 02824 if (option_debug) 02825 ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode); 02826 ast_udptl_setnat(p->udptl, natflags); 02827 } 02828 }
static int does_peer_need_mwi | ( | struct sip_peer * | peer | ) | [static] |
Check whether peer needs a new MWI notification check.
Definition at line 16622 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.
16623 { 16624 time_t t = time(NULL); 16625 16626 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 16627 !peer->mwipvt) { /* We don't have a subscription */ 16628 peer->lastmsgcheck = t; /* Reset timer */ 16629 return FALSE; 16630 } 16631 16632 if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime) 16633 return TRUE; 16634 16635 return FALSE; 16636 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 10814 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
10815 { 10816 switch (mode) { 10817 case SIP_DOMAIN_AUTO: 10818 return "[Automatic]"; 10819 case SIP_DOMAIN_CONFIG: 10820 return "[Configured]"; 10821 } 10822 10823 return ""; 10824 }
static const char * dtmfmode2str | ( | int | mode | ) | const [static] |
Convert DTMF mode to printable string.
Definition at line 10594 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().
10595 { 10596 switch (mode) { 10597 case SIP_DTMF_RFC2833: 10598 return "rfc2833"; 10599 case SIP_DTMF_INFO: 10600 return "info"; 10601 case SIP_DTMF_INBAND: 10602 return "inband"; 10603 case SIP_DTMF_AUTO: 10604 return "auto"; 10605 } 10606 return "<error>"; 10607 }
static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 8233 of file chan_sip.c.
References sip_peer::addr, ast_device_state_changed(), ast_test_flag, ASTOBJ_CONTAINER_UNLINK, ASTOBJ_UNREF, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, FALSE, sip_peer::flags, manager_event(), sip_peer::name, peerl, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RTAUTOCLEAR, and SIP_PAGE2_SELFDESTRUCT.
Referenced by parse_register_contact(), and reg_source_db().
08234 { 08235 struct sip_peer *peer = (struct sip_peer *)data; 08236 08237 if (!peer) /* Hmmm. We have no peer. Weird. */ 08238 return 0; 08239 08240 memset(&peer->addr, 0, sizeof(peer->addr)); 08241 08242 destroy_association(peer); /* remove registration data from storage */ 08243 08244 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08245 register_peer_exten(peer, FALSE); /* Remove regexten */ 08246 peer->expire = -1; 08247 ast_device_state_changed("SIP/%s", peer->name); 08248 08249 /* Do we need to release this peer from memory? 08250 Only for realtime peers and autocreated peers 08251 */ 08252 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) || 08253 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 08254 struct sip_peer *peer_ptr = peer_ptr; 08255 peer_ptr = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); 08256 if (peer_ptr) { 08257 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08258 } 08259 } 08260 08261 ASTOBJ_UNREF(peer, sip_destroy_peer); 08262 08263 return 0; 08264 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 7147 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().
07148 { 07149 char stripped[SIPBUFSIZE]; 07150 char *c; 07151 07152 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 07153 c = get_in_brackets(stripped); 07154 c = strsep(&c, ";"); /* trim ; and beyond */ 07155 if (!ast_strlen_zero(c)) 07156 ast_string_field_set(p, uri, c); 07157 }
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 4360 of file chan_sip.c.
References aliases.
04361 { 04362 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 04363 static const struct cfalias { 04364 char * const fullname; 04365 char * const shortname; 04366 } aliases[] = { 04367 { "Content-Type", "c" }, 04368 { "Content-Encoding", "e" }, 04369 { "From", "f" }, 04370 { "Call-ID", "i" }, 04371 { "Contact", "m" }, 04372 { "Content-Length", "l" }, 04373 { "Subject", "s" }, 04374 { "To", "t" }, 04375 { "Supported", "k" }, 04376 { "Refer-To", "r" }, 04377 { "Referred-By", "b" }, 04378 { "Allow-Events", "u" }, 04379 { "Event", "o" }, 04380 { "Via", "v" }, 04381 { "Accept-Contact", "a" }, 04382 { "Reject-Contact", "j" }, 04383 { "Request-Disposition", "d" }, 04384 { "Session-Expires", "x" }, 04385 { "Identity", "y" }, 04386 { "Identity-Info", "n" }, 04387 }; 04388 int x; 04389 04390 for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 04391 if (!strcasecmp(aliases[x].fullname, name)) 04392 return aliases[x].shortname; 04393 04394 return _default; 04395 }
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 4732 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().
04733 { 04734 struct sip_pvt *p = NULL; 04735 char *tag = ""; /* note, tag is never NULL */ 04736 char totag[128]; 04737 char fromtag[128]; 04738 const char *callid = get_header(req, "Call-ID"); 04739 const char *from = get_header(req, "From"); 04740 const char *to = get_header(req, "To"); 04741 const char *cseq = get_header(req, "Cseq"); 04742 04743 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 04744 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 04745 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 04746 ast_strlen_zero(from) || ast_strlen_zero(cseq)) 04747 return NULL; /* Invalid packet */ 04748 04749 if (pedanticsipchecking) { 04750 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 04751 we need more to identify a branch - so we have to check branch, from 04752 and to tags to identify a call leg. 04753 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 04754 in sip.conf 04755 */ 04756 if (gettag(req, "To", totag, sizeof(totag))) 04757 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 04758 gettag(req, "From", fromtag, sizeof(fromtag)); 04759 04760 tag = (req->method == SIP_RESPONSE) ? totag : fromtag; 04761 04762 if (option_debug > 4 ) 04763 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); 04764 } 04765 04766 ast_mutex_lock(&iflock); 04767 for (p = iflist; p; p = p->next) { 04768 /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 04769 int found = FALSE; 04770 if (ast_strlen_zero(p->callid)) 04771 continue; 04772 if (req->method == SIP_REGISTER) 04773 found = (!strcmp(p->callid, callid)); 04774 else { 04775 found = !strcmp(p->callid, callid); 04776 if (pedanticsipchecking && found) { 04777 found = ast_strlen_zero(tag) || ast_strlen_zero(p->theirtag) || !ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED) || !strcmp(p->theirtag, tag); 04778 } 04779 } 04780 04781 if (option_debug > 4) 04782 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); 04783 04784 /* If we get a new request within an existing to-tag - check the to tag as well */ 04785 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 04786 if (p->tag[0] == '\0' && totag[0]) { 04787 /* We have no to tag, but they have. Wrong dialog */ 04788 found = FALSE; 04789 } else if (totag[0]) { /* Both have tags, compare them */ 04790 if (strcmp(totag, p->tag)) { 04791 found = FALSE; /* This is not our packet */ 04792 } 04793 } 04794 if (!found && option_debug > 4) 04795 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); 04796 } 04797 if (found) { 04798 /* Found the call */ 04799 ast_mutex_lock(&p->lock); 04800 ast_mutex_unlock(&iflock); 04801 return p; 04802 } 04803 } 04804 ast_mutex_unlock(&iflock); 04805 04806 /* See if the method is capable of creating a dialog */ 04807 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 04808 if (intended_method == SIP_REFER) { 04809 /* We do support REFER, but not outside of a dialog yet */ 04810 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 04811 } else if (intended_method == SIP_NOTIFY) { 04812 /* We do not support out-of-dialog NOTIFY either, 04813 like voicemail notification, so cancel that early */ 04814 transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); 04815 } else { 04816 /* Ok, time to create a new SIP dialog object, a pvt */ 04817 if ((p = sip_alloc(callid, sin, 1, intended_method))) { 04818 /* Ok, we've created a dialog, let's go and process it */ 04819 ast_mutex_lock(&p->lock); 04820 } else { 04821 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 04822 getting a dialog from sip_alloc. 04823 04824 Without a dialog we can't retransmit and handle ACKs and all that, but at least 04825 send an error message. 04826 04827 Sorry, we apologize for the inconvienience 04828 */ 04829 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 04830 if (option_debug > 3) 04831 ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 04832 } 04833 } 04834 return p; 04835 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 04836 /* A method we do not support, let's take it on the volley */ 04837 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 04838 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 04839 /* This is a request outside of a dialog that we don't know about 04840 ...never reply to an ACK! 04841 */ 04842 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 04843 } 04844 /* We do not respond to responses for dialogs that we don't know about, we just drop 04845 the session quickly */ 04846 04847 return p; 04848 }
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 2359 of file chan_sip.c.
References s.
Referenced by get_in_brackets().
02360 { 02361 char last_char = '\0'; 02362 const char *s; 02363 for (s = start; *s && s != lim; last_char = *s++) { 02364 if (*s == '"' && last_char != '\\') 02365 break; 02366 } 02367 return s; 02368 }
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 2721 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().
02722 { 02723 struct sip_peer *p = NULL; 02724 02725 if (peer) 02726 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 02727 else 02728 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); 02729 02730 if (!p && (realtime || devstate_only)) 02731 p = realtime_peer(peer, sin, devstate_only); 02732 02733 return p; 02734 }
static struct sip_auth * find_realm_authentication | ( | struct sip_auth * | authlist, | |
const char * | realm | |||
) | [static] |
Find authentication for a specific realm.
Definition at line 17454 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
17455 { 17456 struct sip_auth *a; 17457 17458 for (a = authlist; a; a = a->next) { 17459 if (!strcasecmp(a->realm, realm)) 17460 break; 17461 } 17462 17463 return a; 17464 }
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 5066 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().
05067 { 05068 const char *content_type; 05069 const char *content_length; 05070 const char *search; 05071 char *boundary; 05072 unsigned int x; 05073 int boundaryisquoted = FALSE; 05074 int found_application_sdp = FALSE; 05075 int found_end_of_headers = FALSE; 05076 05077 content_length = get_header(req, "Content-Length"); 05078 05079 if (!ast_strlen_zero(content_length)) { 05080 if (sscanf(content_length, "%30u", &x) != 1) { 05081 ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length); 05082 return 0; 05083 } 05084 05085 /* Content-Length of zero means there can't possibly be an 05086 SDP here, even if the Content-Type says there is */ 05087 if (x == 0) 05088 return 0; 05089 } 05090 05091 content_type = get_header(req, "Content-Type"); 05092 05093 /* if the body contains only SDP, this is easy */ 05094 if (!strncasecmp(content_type, "application/sdp", 15)) { 05095 req->sdp_start = 0; 05096 req->sdp_end = req->lines; 05097 return req->lines ? 1 : 0; 05098 } 05099 05100 /* if it's not multipart/mixed, there cannot be an SDP */ 05101 if (strncasecmp(content_type, "multipart/mixed", 15)) 05102 return 0; 05103 05104 /* if there is no boundary marker, it's invalid */ 05105 if ((search = strcasestr(content_type, ";boundary="))) 05106 search += 10; 05107 else if ((search = strcasestr(content_type, "; boundary="))) 05108 search += 11; 05109 else 05110 return 0; 05111 05112 if (ast_strlen_zero(search)) 05113 return 0; 05114 05115 /* If the boundary is quoted with ", remove quote */ 05116 if (*search == '\"') { 05117 search++; 05118 boundaryisquoted = TRUE; 05119 } 05120 05121 /* make a duplicate of the string, with two extra characters 05122 at the beginning */ 05123 boundary = ast_strdupa(search - 2); 05124 boundary[0] = boundary[1] = '-'; 05125 /* Remove final quote */ 05126 if (boundaryisquoted) 05127 boundary[strlen(boundary) - 1] = '\0'; 05128 05129 /* search for the boundary marker, the empty line delimiting headers from 05130 sdp part and the end boundry if it exists */ 05131 05132 for (x = 0; x < (req->lines ); x++) { 05133 if(!strncasecmp(req->line[x], boundary, strlen(boundary))){ 05134 if(found_application_sdp && found_end_of_headers){ 05135 req->sdp_end = x-1; 05136 return 1; 05137 } 05138 found_application_sdp = FALSE; 05139 } 05140 if(!strcasecmp(req->line[x], "Content-Type: application/sdp")) 05141 found_application_sdp = TRUE; 05142 05143 if(strlen(req->line[x]) == 0 ){ 05144 if(found_application_sdp && !found_end_of_headers){ 05145 req->sdp_start = x; 05146 found_end_of_headers = TRUE; 05147 } 05148 } 05149 } 05150 if(found_application_sdp && found_end_of_headers) { 05151 req->sdp_end = x; 05152 return TRUE; 05153 } 05154 return FALSE; 05155 }
static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 1702 of file chan_sip.c.
References ast_strlen_zero(), method_match(), and sip_methods.
Referenced by __sip_pretend_ack(), handle_response(), sip_hangup(), and sipsock_read().
01703 { 01704 int i, res = 0; 01705 01706 if (ast_strlen_zero(msg)) 01707 return 0; 01708 for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) { 01709 if (method_match(i, msg)) 01710 res = sip_methods[i].id; 01711 } 01712 return res; 01713 }
static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static] |
Find subscription type in array.
Definition at line 11302 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
11303 { 11304 int i; 11305 11306 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 11307 if (subscription_types[i].type == subtype) { 11308 return &subscription_types[i]; 11309 } 11310 } 11311 return &subscription_types[0]; 11312 }
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 2800 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.
02801 { 02802 struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name); 02803 if (!u && realtime) 02804 u = realtime_user(name); 02805 return u; 02806 }
static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 8612 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
08613 { 08614 struct sip_route *next; 08615 08616 while (route) { 08617 next = route->next; 08618 free(route); 08619 route = next; 08620 } 08621 }
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 12328 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), and check_sip_domain().
12329 { 12330 if (ast_strlen_zero(data)) { 12331 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 12332 return -1; 12333 } 12334 if (check_sip_domain(data, NULL, 0)) 12335 ast_copy_string(buf, data, len); 12336 else 12337 buf[0] = '\0'; 12338 return 0; 12339 }
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 12264 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.
12265 { 12266 struct sip_pvt *p; 12267 const char *content = NULL; 12268 AST_DECLARE_APP_ARGS(args, 12269 AST_APP_ARG(header); 12270 AST_APP_ARG(number); 12271 ); 12272 int i, number, start = 0; 12273 12274 if (ast_strlen_zero(data)) { 12275 ast_log(LOG_WARNING, "This function requires a header name.\n"); 12276 return -1; 12277 } 12278 12279 ast_channel_lock(chan); 12280 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 12281 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 12282 ast_channel_unlock(chan); 12283 return -1; 12284 } 12285 12286 AST_STANDARD_APP_ARGS(args, data); 12287 if (!args.number) { 12288 number = 1; 12289 } else { 12290 sscanf(args.number, "%30d", &number); 12291 if (number < 1) 12292 number = 1; 12293 } 12294 12295 p = chan->tech_pvt; 12296 12297 /* If there is no private structure, this channel is no longer alive */ 12298 if (!p) { 12299 ast_channel_unlock(chan); 12300 return -1; 12301 } 12302 12303 for (i = 0; i < number; i++) 12304 content = __get_header(&p->initreq, args.header, &start); 12305 12306 if (ast_strlen_zero(content)) { 12307 ast_channel_unlock(chan); 12308 return -1; 12309 } 12310 12311 ast_copy_string(buf, content, len); 12312 ast_channel_unlock(chan); 12313 12314 return 0; 12315 }
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 12447 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.
12448 { 12449 struct sip_pvt *p; 12450 12451 *buf = 0; 12452 12453 if (!data) { 12454 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 12455 return -1; 12456 } 12457 12458 ast_channel_lock(chan); 12459 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 12460 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 12461 ast_channel_unlock(chan); 12462 return -1; 12463 } 12464 12465 p = chan->tech_pvt; 12466 12467 /* If there is no private structure, this channel is no longer alive */ 12468 if (!p) { 12469 ast_channel_unlock(chan); 12470 return -1; 12471 } 12472 12473 if (!strcasecmp(data, "peerip")) { 12474 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 12475 } else if (!strcasecmp(data, "recvip")) { 12476 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 12477 } else if (!strcasecmp(data, "from")) { 12478 ast_copy_string(buf, p->from, len); 12479 } else if (!strcasecmp(data, "uri")) { 12480 ast_copy_string(buf, p->uri, len); 12481 } else if (!strcasecmp(data, "useragent")) { 12482 ast_copy_string(buf, p->useragent, len); 12483 } else if (!strcasecmp(data, "peername")) { 12484 ast_copy_string(buf, p->peername, len); 12485 } else if (!strcasecmp(data, "t38passthrough")) { 12486 if (p->t38.state == T38_DISABLED) 12487 ast_copy_string(buf, "0", sizeof("0")); 12488 else /* T38 is offered or enabled in this call */ 12489 ast_copy_string(buf, "1", sizeof("1")); 12490 } else { 12491 ast_channel_unlock(chan); 12492 return -1; 12493 } 12494 ast_channel_unlock(chan); 12495 12496 return 0; 12497 }
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 12353 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.
12354 { 12355 struct sip_peer *peer; 12356 char *colname; 12357 12358 if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */ 12359 *colname++ = '\0'; 12360 else if ((colname = strchr(data, '|'))) 12361 *colname++ = '\0'; 12362 else 12363 colname = "ip"; 12364 12365 if (!(peer = find_peer(data, NULL, 1, 0))) 12366 return -1; 12367 12368 if (!strcasecmp(colname, "ip")) { 12369 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 12370 } else if (!strcasecmp(colname, "status")) { 12371 peer_status(peer, buf, len); 12372 } else if (!strcasecmp(colname, "language")) { 12373 ast_copy_string(buf, peer->language, len); 12374 } else if (!strcasecmp(colname, "regexten")) { 12375 ast_copy_string(buf, peer->regexten, len); 12376 } else if (!strcasecmp(colname, "limit")) { 12377 snprintf(buf, len, "%d", peer->call_limit); 12378 } else if (!strcasecmp(colname, "curcalls")) { 12379 snprintf(buf, len, "%d", peer->inUse); 12380 } else if (!strcasecmp(colname, "accountcode")) { 12381 ast_copy_string(buf, peer->accountcode, len); 12382 } else if (!strcasecmp(colname, "useragent")) { 12383 ast_copy_string(buf, peer->useragent, len); 12384 } else if (!strcasecmp(colname, "mailbox")) { 12385 ast_copy_string(buf, peer->mailbox, len); 12386 } else if (!strcasecmp(colname, "context")) { 12387 ast_copy_string(buf, peer->context, len); 12388 } else if (!strcasecmp(colname, "expire")) { 12389 snprintf(buf, len, "%d", peer->expire); 12390 } else if (!strcasecmp(colname, "dynamic")) { 12391 ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 12392 } else if (!strcasecmp(colname, "callerid_name")) { 12393 ast_copy_string(buf, peer->cid_name, len); 12394 } else if (!strcasecmp(colname, "callerid_num")) { 12395 ast_copy_string(buf, peer->cid_num, len); 12396 } else if (!strcasecmp(colname, "codecs")) { 12397 ast_getformatname_multiple(buf, len -1, peer->capability); 12398 } else if (!strncasecmp(colname, "codec[", 6)) { 12399 char *codecnum; 12400 int index = 0, codec = 0; 12401 12402 codecnum = colname + 6; /* move past the '[' */ 12403 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 12404 index = atoi(codecnum); 12405 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 12406 ast_copy_string(buf, ast_getformatname(codec), len); 12407 } else { 12408 buf[0] = '\0'; 12409 } 12410 } else { 12411 buf[0] = '\0'; 12412 } 12413 12414 ASTOBJ_UNREF(peer, sip_destroy_peer); 12415 12416 return 0; 12417 }
static char * generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 4552 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), and build_callid_registry().
04553 { 04554 long val[4]; 04555 int x; 04556 04557 for (x=0; x<4; x++) 04558 val[x] = ast_random(); 04559 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 04560 04561 return buf; 04562 }
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 9660 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().
09661 { 09662 char tmp[256] = "", *c, *a; 09663 struct sip_request *req = oreq ? oreq : &p->initreq; 09664 struct sip_refer *referdata = NULL; 09665 const char *transfer_context = NULL; 09666 09667 if (!p->refer && !sip_refer_allocate(p)) 09668 return -1; 09669 09670 referdata = p->refer; 09671 09672 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 09673 c = get_in_brackets(tmp); 09674 09675 if (pedanticsipchecking) 09676 ast_uri_decode(c); 09677 09678 if (strncasecmp(c, "sip:", 4)) { 09679 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 09680 return -1; 09681 } 09682 c += 4; 09683 if ((a = strchr(c, ';'))) /* Remove arguments */ 09684 *a = '\0'; 09685 09686 if ((a = strchr(c, '@'))) { /* Separate Domain */ 09687 *a++ = '\0'; 09688 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 09689 } 09690 09691 if (sip_debug_test_pvt(p)) 09692 ast_verbose("Looking for %s in %s\n", c, p->context); 09693 09694 if (p->owner) /* Mimic behaviour in res_features.c */ 09695 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 09696 09697 /* By default, use the context in the channel sending the REFER */ 09698 if (ast_strlen_zero(transfer_context)) { 09699 transfer_context = S_OR(p->owner->macrocontext, 09700 S_OR(p->context, default_context)); 09701 } 09702 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 09703 /* This is a blind transfer */ 09704 if (option_debug) 09705 ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 09706 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 09707 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 09708 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 09709 referdata->refer_call = NULL; 09710 /* Set new context */ 09711 ast_string_field_set(p, context, transfer_context); 09712 return 0; 09713 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 09714 return 1; 09715 } 09716 09717 return -1; 09718 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
Get a specific line from the message body.
Definition at line 4344 of file chan_sip.c.
References get_body_by_line(), len(), sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
04345 { 04346 int x; 04347 int len = strlen(name); 04348 char *r; 04349 04350 for (x = 0; x < req->lines; x++) { 04351 r = get_body_by_line(req->line[x], name, len); 04352 if (r[0] != '\0') 04353 return r; 04354 } 04355 04356 return ""; 04357 }
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 4310 of file chan_sip.c.
References ast_skip_blanks().
Referenced by get_body(), and get_sdp_iterate().
04311 { 04312 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') 04313 return ast_skip_blanks(line + nameLen + 1); 04314 04315 return ""; 04316 }
static char * get_calleridname | ( | const char * | input, | |
char * | output, | |||
size_t | outputsize | |||
) | [static] |
Get caller id name from SIP headers.
Definition at line 9772 of file chan_sip.c.
References ast_copy_string(), and ast_skip_blanks().
Referenced by check_user_full().
09773 { 09774 const char *end = strchr(input,'<'); /* first_bracket */ 09775 const char *tmp = strchr(input,'"'); /* first quote */ 09776 int bytes = 0; 09777 int maxbytes = outputsize - 1; 09778 09779 if (!end || end == input) /* we require a part in brackets */ 09780 return NULL; 09781 09782 end--; /* move just before "<" */ 09783 09784 if (tmp && tmp <= end) { 09785 /* The quote (tmp) precedes the bracket (end+1). 09786 * Find the matching quote and return the content. 09787 */ 09788 end = strchr(tmp+1, '"'); 09789 if (!end) 09790 return NULL; 09791 bytes = (int) (end - tmp); 09792 /* protect the output buffer */ 09793 if (bytes > maxbytes) 09794 bytes = maxbytes; 09795 ast_copy_string(output, tmp + 1, bytes); 09796 } else { 09797 /* No quoted string, or it is inside brackets. */ 09798 /* clear the empty characters in the begining*/ 09799 input = ast_skip_blanks(input); 09800 /* clear the empty characters in the end */ 09801 while(*end && *end < 33 && end > input) 09802 end--; 09803 if (end >= input) { 09804 bytes = (int) (end - input) + 2; 09805 /* protect the output buffer */ 09806 if (bytes > maxbytes) 09807 bytes = maxbytes; 09808 ast_copy_string(output, input, bytes); 09809 } else 09810 return NULL; 09811 } 09812 return output; 09813 }
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 9303 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().
09304 { 09305 char tmp[256] = "", *uri, *a; 09306 char tmpf[256] = "", *from; 09307 struct sip_request *req; 09308 char *colon; 09309 char *decoded_uri; 09310 09311 req = oreq; 09312 if (!req) 09313 req = &p->initreq; 09314 09315 /* Find the request URI */ 09316 if (req->rlPart2) 09317 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 09318 09319 if (pedanticsipchecking) 09320 ast_uri_decode(tmp); 09321 09322 uri = get_in_brackets(tmp); 09323 09324 if (strncasecmp(uri, "sip:", 4)) { 09325 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 09326 return -1; 09327 } 09328 uri += 4; 09329 09330 /* Now find the From: caller ID and name */ 09331 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 09332 if (!ast_strlen_zero(tmpf)) { 09333 if (pedanticsipchecking) 09334 ast_uri_decode(tmpf); 09335 from = get_in_brackets(tmpf); 09336 } else { 09337 from = NULL; 09338 } 09339 09340 if (!ast_strlen_zero(from)) { 09341 if (strncasecmp(from, "sip:", 4)) { 09342 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 09343 return -1; 09344 } 09345 from += 4; 09346 if ((a = strchr(from, '@'))) 09347 *a++ = '\0'; 09348 else 09349 a = from; /* just a domain */ 09350 from = strsep(&from, ";"); /* Remove userinfo options */ 09351 a = strsep(&a, ";"); /* Remove URI options */ 09352 ast_string_field_set(p, fromdomain, a); 09353 } 09354 09355 /* Skip any options and find the domain */ 09356 09357 /* Get the target domain */ 09358 if ((a = strchr(uri, '@'))) { 09359 *a++ = '\0'; 09360 } else { /* No username part */ 09361 a = uri; 09362 uri = "s"; /* Set extension to "s" */ 09363 } 09364 colon = strchr(a, ':'); /* Remove :port */ 09365 if (colon) 09366 *colon = '\0'; 09367 09368 uri = strsep(&uri, ";"); /* Remove userinfo options */ 09369 a = strsep(&a, ";"); /* Remove URI options */ 09370 09371 ast_string_field_set(p, domain, a); 09372 09373 if (!AST_LIST_EMPTY(&domain_list)) { 09374 char domain_context[AST_MAX_EXTENSION]; 09375 09376 domain_context[0] = '\0'; 09377 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 09378 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 09379 if (option_debug) 09380 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 09381 return -2; 09382 } 09383 } 09384 /* If we have a context defined, overwrite the original context */ 09385 if (!ast_strlen_zero(domain_context)) 09386 ast_string_field_set(p, context, domain_context); 09387 } 09388 09389 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 09390 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) 09391 ast_string_field_set(p, context, p->subscribecontext); 09392 09393 if (sip_debug_test_pvt(p)) 09394 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 09395 09396 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 09397 if (req->method == SIP_SUBSCRIBE) { 09398 char hint[AST_MAX_EXTENSION]; 09399 return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1); 09400 } else { 09401 decoded_uri = ast_strdupa(uri); 09402 ast_uri_decode(decoded_uri); 09403 /* Check the dialplan for the username part of the request URI, 09404 the domain will be stored in the SIPDOMAIN variable 09405 Since extensions.conf can have unescaped characters, try matching a decoded 09406 uri in addition to the non-decoded uri 09407 Return 0 if we have a matching extension */ 09408 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)) || 09409 !strcmp(decoded_uri, ast_pickup_ext())) { 09410 if (!oreq) 09411 ast_string_field_set(p, exten, decoded_uri); 09412 return 0; 09413 } 09414 } 09415 09416 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 09417 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 09418 ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))) || 09419 !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri))) { 09420 return 1; 09421 } 09422 09423 return -1; 09424 }
static const char * get_header | ( | const struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get header from SIP request.
Definition at line 4433 of file chan_sip.c.
References __get_header().
04434 { 04435 int start = 0; 04436 return __get_header(req, name, &start); 04437 }
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 2381 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().
02382 { 02383 const char *parse = tmp; 02384 char *first_bracket; 02385 02386 /* 02387 * Skip any quoted text until we find the part in brackets. 02388 * On any error give up and return the full string. 02389 */ 02390 while ( (first_bracket = strchr(parse, '<')) ) { 02391 char *first_quote = strchr(parse, '"'); 02392 02393 if (!first_quote || first_quote > first_bracket) 02394 break; /* no need to look at quoted part */ 02395 /* the bracket is within quotes, so ignore it */ 02396 parse = find_closing_quote(first_quote + 1, NULL); 02397 if (!*parse) { /* not found, return full string ? */ 02398 /* XXX or be robust and return in-bracket part ? */ 02399 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 02400 break; 02401 } 02402 parse++; 02403 } 02404 if (first_bracket) { 02405 char *second_bracket = strchr(first_bracket + 1, '>'); 02406 if (second_bracket) { 02407 *second_bracket = '\0'; 02408 tmp = first_bracket + 1; 02409 } else { 02410 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 02411 } 02412 } 02413 return tmp; 02414 }
static int get_ip_and_port_from_sdp | ( | struct sip_request * | req, | |
const enum media_type | media, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 5189 of file chan_sip.c.
References ast_gethostbyname(), ast_log(), ast_strlen_zero(), get_sdp_iterate(), hp, len(), SDP_AUDIO, sip_request::sdp_start, and SDP_VIDEO.
Referenced by handle_request_invite().
05190 { 05191 const char *m; 05192 const char *c; 05193 int miterator = req->sdp_start; 05194 int citerator = req->sdp_start; 05195 int x = 0; 05196 int numberofports; 05197 int len; 05198 char host[258] = ""; /*Initialize to empty so we will know if we have any input */ 05199 struct ast_hostent audiohp; 05200 struct hostent *hp; 05201 05202 c = get_sdp_iterate(&citerator, req, "c"); 05203 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05204 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 05205 /* Continue since there may be a valid host in a c= line specific to the audio stream */ 05206 } 05207 /* We only want the m and c lines for audio */ 05208 for (m = get_sdp_iterate(&miterator, req, "m"); !ast_strlen_zero(m); m = get_sdp_iterate(&miterator, req, "m")) { 05209 if ((media == SDP_AUDIO && ((sscanf(m, "audio %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05210 (sscanf(m, "audio %30d RTP/AVP %n", &x, &len) == 1 && len > 0))) || 05211 (media == SDP_VIDEO && ((sscanf(m, "video %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05212 (sscanf(m, "video %30d RTP/AVP %n", &x, &len) == 1 && len > 0)))) { 05213 /* See if there's a c= line for this media stream. 05214 * XXX There is no guarantee that we'll be grabbing the c= line for this 05215 * particular media stream here. However, this is the same logic used in process_sdp. 05216 */ 05217 c = get_sdp_iterate(&citerator, req, "c"); 05218 if (!ast_strlen_zero(c)) { 05219 sscanf(c, "IN IP4 %256s", host); 05220 } 05221 break; 05222 } 05223 } 05224 05225 if (ast_strlen_zero(host) || x == 0) { 05226 ast_log(LOG_WARNING, "Failed to read an alternate host or port in SDP. Expect %s problems\n", media == SDP_AUDIO ? "audio" : "video"); 05227 return -1; 05228 } 05229 05230 hp = ast_gethostbyname(host, &audiohp); 05231 if (!hp) { 05232 ast_log(LOG_WARNING, "Could not look up IP address of alternate hostname. Expect %s problems\n", media == SDP_AUDIO? "audio" : "video"); 05233 return -1; 05234 } 05235 05236 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 05237 sin->sin_port = htons(x); 05238 return 0; 05239 }
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 10187 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_notify(), and receive_message().
10188 { 10189 int x; 10190 int y; 10191 10192 buf[0] = '\0'; 10193 y = len - strlen(buf) - 5; 10194 if (y < 0) 10195 y = 0; 10196 for (x=0;x<req->lines;x++) { 10197 strncat(buf, req->line[x], y); /* safe */ 10198 y -= strlen(req->line[x]) + 1; 10199 if (y < 0) 10200 y = 0; 10201 if (y != 0) 10202 strcat(buf, "\n"); /* safe */ 10203 } 10204 return 0; 10205 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Get referring dnis.
Definition at line 9274 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().
09275 { 09276 char tmp[256], *c, *a; 09277 struct sip_request *req; 09278 09279 req = oreq; 09280 if (!req) 09281 req = &p->initreq; 09282 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 09283 if (ast_strlen_zero(tmp)) 09284 return 0; 09285 c = get_in_brackets(tmp); 09286 if (strncasecmp(c, "sip:", 4)) { 09287 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 09288 return -1; 09289 } 09290 c += 4; 09291 a = c; 09292 strsep(&a, "@;"); /* trim anything after @ or ; */ 09293 if (sip_debug_test_pvt(p)) 09294 ast_verbose("RDNIS is %s\n", c); 09295 ast_string_field_set(p, rdnis, c); 09296 09297 return 0; 09298 }
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 9497 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().
09498 { 09499 09500 const char *p_referred_by = NULL; 09501 char *h_refer_to = NULL; 09502 char *h_referred_by = NULL; 09503 char *refer_to; 09504 const char *p_refer_to; 09505 char *referred_by_uri = NULL; 09506 char *ptr; 09507 struct sip_request *req = NULL; 09508 const char *transfer_context = NULL; 09509 struct sip_refer *referdata; 09510 09511 09512 req = outgoing_req; 09513 referdata = transferer->refer; 09514 09515 if (!req) 09516 req = &transferer->initreq; 09517 09518 p_refer_to = get_header(req, "Refer-To"); 09519 if (ast_strlen_zero(p_refer_to)) { 09520 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 09521 return -2; /* Syntax error */ 09522 } 09523 h_refer_to = ast_strdupa(p_refer_to); 09524 refer_to = get_in_brackets(h_refer_to); 09525 if (pedanticsipchecking) 09526 ast_uri_decode(refer_to); 09527 09528 if (strncasecmp(refer_to, "sip:", 4)) { 09529 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 09530 return -3; 09531 } 09532 refer_to += 4; /* Skip sip: */ 09533 09534 /* Get referred by header if it exists */ 09535 p_referred_by = get_header(req, "Referred-By"); 09536 if (!ast_strlen_zero(p_referred_by)) { 09537 char *lessthan; 09538 h_referred_by = ast_strdupa(p_referred_by); 09539 if (pedanticsipchecking) 09540 ast_uri_decode(h_referred_by); 09541 09542 /* Store referrer's caller ID name */ 09543 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 09544 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 09545 *(lessthan - 1) = '\0'; /* Space */ 09546 } 09547 09548 referred_by_uri = get_in_brackets(h_referred_by); 09549 if(strncasecmp(referred_by_uri, "sip:", 4)) { 09550 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 09551 referred_by_uri = (char *) NULL; 09552 } else { 09553 referred_by_uri += 4; /* Skip sip: */ 09554 } 09555 } 09556 09557 /* Check for arguments in the refer_to header */ 09558 if ((ptr = strcasestr(refer_to, "replaces="))) { 09559 char *to = NULL, *from = NULL; 09560 09561 /* This is an attended transfer */ 09562 referdata->attendedtransfer = 1; 09563 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 09564 ast_uri_decode(referdata->replaces_callid); 09565 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 09566 *ptr++ = '\0'; 09567 } 09568 09569 if (ptr) { 09570 /* Find the different tags before we destroy the string */ 09571 to = strcasestr(ptr, "to-tag="); 09572 from = strcasestr(ptr, "from-tag="); 09573 } 09574 09575 /* Grab the to header */ 09576 if (to) { 09577 ptr = to + 7; 09578 if ((to = strchr(ptr, '&'))) 09579 *to = '\0'; 09580 if ((to = strchr(ptr, ';'))) 09581 *to = '\0'; 09582 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 09583 } 09584 09585 if (from) { 09586 ptr = from + 9; 09587 if ((to = strchr(ptr, '&'))) 09588 *to = '\0'; 09589 if ((to = strchr(ptr, ';'))) 09590 *to = '\0'; 09591 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 09592 } 09593 09594 if (option_debug > 1) { 09595 if (!pedanticsipchecking) 09596 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 09597 else 09598 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>" ); 09599 } 09600 } 09601 09602 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 09603 char *urioption = NULL, *domain; 09604 *ptr++ = '\0'; 09605 09606 if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */ 09607 *urioption++ = '\0'; 09608 09609 domain = ptr; 09610 if ((ptr = strchr(domain, ':'))) /* Remove :port */ 09611 *ptr = '\0'; 09612 09613 /* Save the domain for the dial plan */ 09614 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 09615 if (urioption) 09616 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 09617 } 09618 09619 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 09620 *ptr = '\0'; 09621 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 09622 09623 if (referred_by_uri) { 09624 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 09625 *ptr = '\0'; 09626 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 09627 } else { 09628 referdata->referred_by[0] = '\0'; 09629 } 09630 09631 /* Determine transfer context */ 09632 if (transferer->owner) /* Mimic behaviour in res_features.c */ 09633 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 09634 09635 /* By default, use the context in the channel sending the REFER */ 09636 if (ast_strlen_zero(transfer_context)) { 09637 transfer_context = S_OR(transferer->owner->macrocontext, 09638 S_OR(transferer->context, default_context)); 09639 } 09640 09641 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 09642 09643 /* Either an existing extension or the parking extension */ 09644 if (referdata->attendedtransfer || ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 09645 if (sip_debug_test_pvt(transferer)) { 09646 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 09647 } 09648 /* We are ready to transfer to the extension */ 09649 return 0; 09650 } 09651 if (sip_debug_test_pvt(transferer)) 09652 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 09653 09654 /* Failure, we can't find this extension */ 09655 return -1; 09656 }
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 9819 of file chan_sip.c.
References ast_copy_string(), and AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
09820 { 09821 char *start; 09822 char *end; 09823 09824 start = strchr(input,':'); 09825 if (!start) { 09826 output[0] = '\0'; 09827 return 0; 09828 } 09829 start++; 09830 09831 /* we found "number" */ 09832 ast_copy_string(output,start,maxlen); 09833 output[maxlen-1] = '\0'; 09834 09835 end = strchr(output,'@'); 09836 if (end) 09837 *end = '\0'; 09838 else 09839 output[0] = '\0'; 09840 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 09841 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 09842 09843 return 0; 09844 }
static const char * get_sdp | ( | struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get a line from an SDP message body.
Definition at line 4336 of file chan_sip.c.
References get_sdp_iterate().
04337 { 04338 int dummy = 0; 04339 04340 return get_sdp_iterate(&dummy, req, name); 04341 }
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 4322 of file chan_sip.c.
References get_body_by_line(), len(), and sip_request::line.
04323 { 04324 int len = strlen(name); 04325 04326 while (*start < req->sdp_end) { 04327 const char *r = get_body_by_line(req->line[(*start)++], name, len); 04328 if (r[0] != '\0') 04329 return r; 04330 } 04331 04332 return ""; 04333 }
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 9428 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().
09429 { 09430 struct sip_pvt *sip_pvt_ptr; 09431 09432 ast_mutex_lock(&iflock); 09433 09434 if (option_debug > 3 && totag) { 09435 ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 09436 } 09437 09438 /* Search interfaces and find the match */ 09439 for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 09440 if (!strcmp(sip_pvt_ptr->callid, callid)) { 09441 int match = 1; 09442 09443 if (option_debug > 3) 09444 ast_log(LOG_DEBUG, "Found call with callid %s (ourtag=%s, theirtag=%s)\n", callid, sip_pvt_ptr->tag, sip_pvt_ptr->theirtag); 09445 09446 /* Go ahead and lock it (and its owner) before returning */ 09447 ast_mutex_lock(&sip_pvt_ptr->lock); 09448 09449 /* Check if tags match. If not, this is not the call we want 09450 * (With a forking SIP proxy, several call legs share the 09451 * call id, but have different tags) 09452 */ 09453 if (pedanticsipchecking) { 09454 /* RFC 3891 09455 * > 3. User Agent Server Behavior: Receiving a Replaces Header 09456 * > The Replaces header contains information used to match an existing 09457 * > SIP dialog (call-id, to-tag, and from-tag). Upon receiving an INVITE 09458 * > with a Replaces header, the User Agent (UA) attempts to match this 09459 * > information with a confirmed or early dialog. The User Agent Server 09460 * > (UAS) matches the to-tag and from-tag parameters as if they were tags 09461 * > present in an incoming request. In other words, the to-tag parameter 09462 * > is compared to the local tag, and the from-tag parameter is compared 09463 * > to the remote tag. 09464 * 09465 * Thus, the totag is always compared to the local tag, regardless if 09466 * this our call is an incoming or outgoing call. 09467 */ 09468 if (ast_strlen_zero(fromtag) || strcmp(fromtag, sip_pvt_ptr->theirtag) || (!ast_strlen_zero(totag) && strcmp(totag, sip_pvt_ptr->tag))) 09469 match = 0; 09470 } 09471 09472 if (!match) { 09473 ast_mutex_unlock(&sip_pvt_ptr->lock); 09474 continue; 09475 } 09476 09477 if (option_debug > 3 && totag) 09478 ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n", 09479 ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_OUTGOING_CALL) ? "OUTGOING": "INCOMING", 09480 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 09481 09482 /* deadlock avoidance... */ 09483 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 09484 DEADLOCK_AVOIDANCE(&sip_pvt_ptr->lock); 09485 } 09486 break; 09487 } 09488 } 09489 ast_mutex_unlock(&iflock); 09490 if (option_debug > 3 && !sip_pvt_ptr) 09491 ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 09492 return sip_pvt_ptr; 09493 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 13909 of file chan_sip.c.
References ast_copy_string(), and get_header().
Referenced by find_call(), handle_request(), handle_request_subscribe(), and handle_response().
13910 { 13911 const char *thetag; 13912 13913 if (!tagbuf) 13914 return NULL; 13915 tagbuf[0] = '\0'; /* reset the buffer */ 13916 thetag = get_header(req, header); 13917 thetag = strcasestr(thetag, ";tag="); 13918 if (thetag) { 13919 thetag += 5; 13920 ast_copy_string(tagbuf, thetag, tagbufsize); 13921 return strsep(&tagbuf, ";"); 13922 } 13923 return NULL; 13924 }
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 17203 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().
17204 { 17205 int res = 1; 17206 17207 if (!strcasecmp(v->name, "trustrpid")) { 17208 ast_set_flag(&mask[0], SIP_TRUSTRPID); 17209 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 17210 } else if (!strcasecmp(v->name, "sendrpid")) { 17211 ast_set_flag(&mask[0], SIP_SENDRPID); 17212 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 17213 } else if (!strcasecmp(v->name, "g726nonstandard")) { 17214 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 17215 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 17216 } else if (!strcasecmp(v->name, "useclientcode")) { 17217 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 17218 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 17219 } else if (!strcasecmp(v->name, "dtmfmode")) { 17220 ast_set_flag(&mask[0], SIP_DTMF); 17221 ast_clear_flag(&flags[0], SIP_DTMF); 17222 if (!strcasecmp(v->value, "inband")) 17223 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 17224 else if (!strcasecmp(v->value, "rfc2833")) 17225 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 17226 else if (!strcasecmp(v->value, "info")) 17227 ast_set_flag(&flags[0], SIP_DTMF_INFO); 17228 else if (!strcasecmp(v->value, "auto")) 17229 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 17230 else { 17231 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 17232 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 17233 } 17234 } else if (!strcasecmp(v->name, "nat")) { 17235 ast_set_flag(&mask[0], SIP_NAT); 17236 ast_clear_flag(&flags[0], SIP_NAT); 17237 if (!strcasecmp(v->value, "never")) 17238 ast_set_flag(&flags[0], SIP_NAT_NEVER); 17239 else if (!strcasecmp(v->value, "route")) 17240 ast_set_flag(&flags[0], SIP_NAT_ROUTE); 17241 else if (ast_true(v->value)) 17242 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 17243 else 17244 ast_set_flag(&flags[0], SIP_NAT_RFC3581); 17245 } else if (!strcasecmp(v->name, "canreinvite")) { 17246 ast_set_flag(&mask[0], SIP_REINVITE); 17247 ast_clear_flag(&flags[0], SIP_REINVITE); 17248 if(ast_true(v->value)) { 17249 ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT); 17250 } else if (!ast_false(v->value)) { 17251 char buf[64]; 17252 char *word, *next = buf; 17253 17254 ast_copy_string(buf, v->value, sizeof(buf)); 17255 while ((word = strsep(&next, ","))) { 17256 if(!strcasecmp(word, "update")) { 17257 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 17258 } else if(!strcasecmp(word, "nonat")) { 17259 ast_set_flag(&flags[0], SIP_CAN_REINVITE); 17260 ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT); 17261 } else { 17262 ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno); 17263 } 17264 } 17265 } 17266 } else if (!strcasecmp(v->name, "insecure")) { 17267 ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 17268 ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 17269 set_insecure_flags(flags, v->value, v->lineno); 17270 } else if (!strcasecmp(v->name, "progressinband")) { 17271 ast_set_flag(&mask[0], SIP_PROG_INBAND); 17272 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 17273 if (ast_true(v->value)) 17274 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 17275 else if (strcasecmp(v->value, "never")) 17276 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 17277 } else if (!strcasecmp(v->name, "promiscredir")) { 17278 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 17279 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 17280 } else if (!strcasecmp(v->name, "videosupport")) { 17281 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 17282 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 17283 } else if (!strcasecmp(v->name, "allowoverlap")) { 17284 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 17285 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 17286 } else if (!strcasecmp(v->name, "allowsubscribe")) { 17287 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 17288 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 17289 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 17290 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 17291 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 17292 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 17293 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 17294 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 17295 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 17296 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 17297 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 17298 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 17299 #endif 17300 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 17301 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 17302 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 17303 } else if (!strcasecmp(v->name, "buggymwi")) { 17304 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 17305 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 17306 } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { 17307 ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); 17308 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); 17309 } else 17310 res = 0; 17311 17312 return res; 17313 }
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 14094 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().
14095 { 14096 struct ast_frame *f; 14097 int earlyreplace = 0; 14098 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 14099 struct ast_channel *c = p->owner; /* Our incoming call */ 14100 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 14101 struct ast_channel *targetcall; /* The bridge to the take-over target */ 14102 14103 /* Check if we're in ring state */ 14104 if (replacecall->_state == AST_STATE_RING) 14105 earlyreplace = 1; 14106 14107 /* Check if we have a bridge */ 14108 if (!(targetcall = ast_bridged_channel(replacecall))) { 14109 /* We have no bridge */ 14110 if (!earlyreplace) { 14111 if (option_debug > 1) 14112 ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 14113 oneleggedreplace = 1; 14114 } 14115 } 14116 if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING) 14117 ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n"); 14118 14119 if (option_debug > 3) { 14120 if (targetcall) 14121 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); 14122 else 14123 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 14124 } 14125 14126 if (ignore) { 14127 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 14128 /* We should answer something here. If we are here, the 14129 call we are replacing exists, so an accepted 14130 can't harm */ 14131 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 14132 /* Do something more clever here */ 14133 ast_channel_unlock(c); 14134 ast_mutex_unlock(&p->refer->refer_call->lock); 14135 return 1; 14136 } 14137 if (!c) { 14138 /* What to do if no channel ??? */ 14139 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 14140 transmit_response_reliable(p, "503 Service Unavailable", req); 14141 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 14142 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14143 ast_mutex_unlock(&p->refer->refer_call->lock); 14144 return 1; 14145 } 14146 append_history(p, "Xfer", "INVITE/Replace received"); 14147 /* We have three channels to play with 14148 channel c: New incoming call 14149 targetcall: Call from PBX to target 14150 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 14151 replacecall: The owner of the previous 14152 We need to masq C into refer_call to connect to 14153 targetcall; 14154 If we are talking to internal audio stream, target call is null. 14155 */ 14156 14157 /* Fake call progress */ 14158 transmit_response(p, "100 Trying", req); 14159 ast_setstate(c, AST_STATE_RING); 14160 14161 /* Masquerade the new call into the referred call to connect to target call 14162 Targetcall is not touched by the masq */ 14163 14164 /* Answer the incoming call and set channel to UP state */ 14165 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 14166 14167 ast_setstate(c, AST_STATE_UP); 14168 14169 /* Stop music on hold and other generators */ 14170 ast_quiet_chan(replacecall); 14171 ast_quiet_chan(targetcall); 14172 if (option_debug > 3) 14173 ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 14174 /* Unlock clone, but not original (replacecall) */ 14175 if (!oneleggedreplace) 14176 ast_channel_unlock(c); 14177 14178 /* Unlock PVT */ 14179 ast_mutex_unlock(&p->refer->refer_call->lock); 14180 14181 /* Make sure that the masq does not free our PVT for the old call */ 14182 if (! earlyreplace && ! oneleggedreplace ) 14183 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14184 14185 /* Prepare the masquerade - if this does not happen, we will be gone */ 14186 if(ast_channel_masquerade(replacecall, c)) 14187 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 14188 else if (option_debug > 3) 14189 ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 14190 14191 /* The masquerade will happen as soon as someone reads a frame from the channel */ 14192 14193 /* C should now be in place of replacecall */ 14194 /* ast_read needs to lock channel */ 14195 ast_channel_unlock(c); 14196 14197 if (earlyreplace || oneleggedreplace ) { 14198 /* Force the masq to happen */ 14199 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 14200 ast_frfree(f); 14201 f = NULL; 14202 if (option_debug > 3) 14203 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from RING channel!\n"); 14204 } else { 14205 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from RING channel \n"); 14206 } 14207 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 14208 if (!oneleggedreplace) 14209 ast_channel_unlock(replacecall); 14210 } else { /* Bridged call, UP channel */ 14211 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 14212 /* Masq ok */ 14213 ast_frfree(f); 14214 f = NULL; 14215 if (option_debug > 2) 14216 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from channel! Masq done.\n"); 14217 } else { 14218 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from channel. Transfer failed\n"); 14219 } 14220 ast_channel_unlock(replacecall); 14221 } 14222 ast_mutex_unlock(&p->refer->refer_call->lock); 14223 14224 ast_setstate(c, AST_STATE_DOWN); 14225 if (option_debug > 3) { 14226 struct ast_channel *test; 14227 ast_log(LOG_DEBUG, "After transfer:----------------------------\n"); 14228 ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 14229 if (replacecall) 14230 ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 14231 if (p->owner) { 14232 ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 14233 test = ast_bridged_channel(p->owner); 14234 if (test) 14235 ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 14236 else 14237 ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n"); 14238 } else 14239 ast_log(LOG_DEBUG, " -- No channel yet \n"); 14240 ast_log(LOG_DEBUG, "End After transfer:----------------------------\n"); 14241 } 14242 14243 ast_channel_unlock(p->owner); /* Unlock new owner */ 14244 if (!oneleggedreplace) 14245 ast_mutex_unlock(&p->lock); /* Unlock SIP structure */ 14246 14247 /* The call should be down with no ast_channel, so hang it up */ 14248 c->tech_pvt = NULL; 14249 ast_hangup(c); 14250 return 0; 14251 }
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 16147 of file chan_sip.c.
References __sip_ack(), 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_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(), and sip_pvt::useragent.
16148 { 16149 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 16150 relatively static */ 16151 const char *cmd; 16152 const char *cseq; 16153 const char *useragent; 16154 int seqno; 16155 int len; 16156 int ignore = FALSE; 16157 int respid; 16158 int res = 0; 16159 int debug = sip_debug_test_pvt(p); 16160 char *e; 16161 int error = 0; 16162 16163 /* Get Method and Cseq */ 16164 cseq = get_header(req, "Cseq"); 16165 cmd = req->header[0]; 16166 16167 /* Must have Cseq */ 16168 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 16169 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 16170 error = 1; 16171 } 16172 if (!error && sscanf(cseq, "%30d%n", &seqno, &len) != 1) { 16173 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 16174 error = 1; 16175 } 16176 if (error) { 16177 if (!p->initreq.headers) /* New call */ 16178 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 16179 return -1; 16180 } 16181 /* Get the command XXX */ 16182 16183 cmd = req->rlPart1; 16184 e = ast_skip_blanks(req->rlPart2); 16185 16186 /* Save useragent of the client */ 16187 useragent = get_header(req, "User-Agent"); 16188 if (!ast_strlen_zero(useragent)) 16189 ast_string_field_set(p, useragent, useragent); 16190 16191 /* Find out SIP method for incoming request */ 16192 if (req->method == SIP_RESPONSE) { /* Response to our request */ 16193 /* Response to our request -- Do some sanity checks */ 16194 if (ast_strlen_zero(e)) { 16195 return 0; 16196 } 16197 if (sscanf(e, "%30d %n", &respid, &len) != 1) { 16198 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 16199 return 0; 16200 } 16201 if (respid <= 0) { 16202 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 16203 return 0; 16204 } 16205 if (!p->initreq.headers) { 16206 if (option_debug) 16207 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 16208 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16209 return 0; 16210 } 16211 if (p->ocseq && (p->ocseq < seqno)) { 16212 if (option_debug) 16213 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 16214 return -1; 16215 } else { 16216 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) { 16217 extract_uri(p, req); 16218 } 16219 handle_response(p, respid, e + len, req, seqno); 16220 } 16221 return 0; 16222 } 16223 16224 /* New SIP request coming in 16225 (could be new request in existing SIP dialog as well...) 16226 */ 16227 16228 p->method = req->method; /* Find out which SIP method they are using */ 16229 if (option_debug > 3) 16230 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 16231 16232 if (p->icseq && (p->icseq > seqno) ) { 16233 if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) { 16234 if (option_debug > 2) 16235 ast_log(LOG_DEBUG, "Got CANCEL or ACK on INVITE with transactions in between.\n"); 16236 } else { 16237 if (option_debug) 16238 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 16239 if (req->method != SIP_ACK) 16240 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 16241 return -1; 16242 } 16243 } else if (p->icseq && 16244 p->icseq == seqno && 16245 req->method != SIP_ACK && 16246 (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) { 16247 /* ignore means "don't do anything with it" but still have to 16248 respond appropriately. We do this if we receive a repeat of 16249 the last sequence number */ 16250 ignore = 2; 16251 ast_set_flag(req, SIP_PKT_IGNORE); 16252 ast_set_flag(req, SIP_PKT_IGNORE_REQ); 16253 if (option_debug > 2) 16254 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 16255 } 16256 16257 if (seqno >= p->icseq) 16258 /* Next should follow monotonically (but not necessarily 16259 incrementally -- thanks again to the genius authors of SIP -- 16260 increasing */ 16261 p->icseq = seqno; 16262 16263 /* Find their tag if we haven't got it */ 16264 if (ast_strlen_zero(p->theirtag)) { 16265 char tag[128]; 16266 16267 gettag(req, "From", tag, sizeof(tag)); 16268 ast_string_field_set(p, theirtag, tag); 16269 } 16270 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 16271 16272 if (pedanticsipchecking) { 16273 /* If this is a request packet without a from tag, it's not 16274 correct according to RFC 3261 */ 16275 /* Check if this a new request in a new dialog with a totag already attached to it, 16276 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 16277 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 16278 /* If this is a first request and it got a to-tag, it is not for us */ 16279 if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) { 16280 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 16281 /* Will cease to exist after ACK */ 16282 } else if (req->method != SIP_ACK) { 16283 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 16284 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16285 } 16286 return res; 16287 } 16288 } 16289 16290 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 16291 transmit_response(p, "400 Bad request", req); 16292 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16293 return -1; 16294 } 16295 16296 /* Handle various incoming SIP methods in requests */ 16297 switch (p->method) { 16298 case SIP_OPTIONS: 16299 res = handle_request_options(p, req); 16300 break; 16301 case SIP_INVITE: 16302 res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock); 16303 break; 16304 case SIP_REFER: 16305 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 16306 break; 16307 case SIP_CANCEL: 16308 res = handle_request_cancel(p, req); 16309 break; 16310 case SIP_BYE: 16311 res = handle_request_bye(p, req); 16312 break; 16313 case SIP_MESSAGE: 16314 res = handle_request_message(p, req); 16315 break; 16316 case SIP_SUBSCRIBE: 16317 res = handle_request_subscribe(p, req, sin, seqno, e); 16318 break; 16319 case SIP_REGISTER: 16320 res = handle_request_register(p, req, sin, e); 16321 break; 16322 case SIP_INFO: 16323 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16324 ast_verbose("Receiving INFO!\n"); 16325 if (!ignore) 16326 handle_request_info(p, req); 16327 else /* if ignoring, transmit response */ 16328 transmit_response(p, "200 OK", req); 16329 break; 16330 case SIP_NOTIFY: 16331 res = handle_request_notify(p, req, sin, seqno, e); 16332 break; 16333 case SIP_ACK: 16334 /* Make sure we don't ignore this */ 16335 if (seqno == p->pendinginvite) { 16336 p->invitestate = INV_TERMINATED; 16337 p->pendinginvite = 0; 16338 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 16339 if (find_sdp(req)) { 16340 if (process_sdp(p, req)) 16341 return -1; 16342 } 16343 check_pendings(p); 16344 } else if (p->glareinvite == seqno) { 16345 /* handle ack for the 491 pending send for glareinvite */ 16346 p->glareinvite = 0; 16347 __sip_ack(p, seqno, 1, 0); 16348 } 16349 /* Got an ACK that we did not match. Ignore silently */ 16350 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 16351 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16352 break; 16353 default: 16354 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 16355 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 16356 cmd, ast_inet_ntoa(p->sa.sin_addr)); 16357 /* If this is some new method, and we don't have a call, destroy it now */ 16358 if (!p->initreq.headers) 16359 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16360 break; 16361 } 16362 return res; 16363 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 15701 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(), ast_channel::context, context, copy_request(), DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, get_also_info(), get_header(), sip_pvt::initreq, INV_TERMINATED, LOG_DEBUG, LOG_NOTICE, option_debug, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_alreadygone(), SIP_NO_HISTORY, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_IGNORE, sip_scheddestroy(), stop_media_flows(), transmit_response(), and transmit_response_reliable().
Referenced by handle_request().
15702 { 15703 struct ast_channel *c=NULL; 15704 int res; 15705 struct ast_channel *bridged_to; 15706 15707 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 15708 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE)) 15709 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 15710 15711 __sip_pretend_ack(p); 15712 15713 p->invitestate = INV_TERMINATED; 15714 15715 copy_request(&p->initreq, req); 15716 check_via(p, req); 15717 sip_alreadygone(p); 15718 15719 /* Get RTCP quality before end of call */ 15720 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { 15721 char *audioqos, *videoqos; 15722 if (p->rtp) { 15723 audioqos = ast_rtp_get_quality(p->rtp, NULL); 15724 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 15725 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 15726 if (p->owner) 15727 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 15728 } 15729 if (p->vrtp) { 15730 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 15731 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 15732 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 15733 if (p->owner) 15734 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 15735 } 15736 } 15737 15738 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 15739 15740 if (!ast_strlen_zero(get_header(req, "Also"))) { 15741 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 15742 ast_inet_ntoa(p->recv.sin_addr)); 15743 if (ast_strlen_zero(p->context)) 15744 ast_string_field_set(p, context, default_context); 15745 res = get_also_info(p, req); 15746 if (!res) { 15747 c = p->owner; 15748 if (c) { 15749 bridged_to = ast_bridged_channel(c); 15750 if (bridged_to) { 15751 /* Don't actually hangup here... */ 15752 ast_queue_control(c, AST_CONTROL_UNHOLD); 15753 ast_async_goto(bridged_to, p->context, p->refer->refer_to,1); 15754 } else 15755 ast_queue_hangup(p->owner); 15756 } 15757 } else { 15758 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 15759 if (p->owner) 15760 ast_queue_hangup(p->owner); 15761 } 15762 } else if (p->owner) { 15763 ast_queue_hangup(p->owner); 15764 if (option_debug > 2) 15765 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n"); 15766 } else { 15767 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15768 if (option_debug > 2) 15769 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n"); 15770 } 15771 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15772 transmit_response(p, "200 OK", req); 15773 15774 return 1; 15775 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 15571 of file chan_sip.c.
References __sip_pretend_ack(), ast_free, ast_log(), ast_queue_hangup(), AST_SCHED_DEL, AST_STATE_UP, ast_test_flag, check_via(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, INV_CANCELLED, INV_TERMINATED, sip_pvt::invitestate, LOG_DEBUG, sip_pkt::next, option_debug, sip_dual::req, sip_pkt::response_code, sip_pkt::retransid, sched, sip_pkt::seqno, sip_alreadygone(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), UNLINK, and update_call_counter().
Referenced by handle_request().
15572 { 15573 15574 check_via(p, req); 15575 sip_alreadygone(p); 15576 15577 /* At this point, we could have cancelled the invite at the same time 15578 as the other side sends a CANCEL. Our final reply with error code 15579 might not have been received by the other side before the CANCEL 15580 was sent, so let's just give up retransmissions and waiting for 15581 ACK on our error code. The call is hanging up any way. */ 15582 if (p->invitestate == INV_TERMINATED) 15583 __sip_pretend_ack(p); 15584 else 15585 p->invitestate = INV_CANCELLED; 15586 15587 if (p->owner && p->owner->_state == AST_STATE_UP) { 15588 /* This call is up, cancel is ignored, we need a bye */ 15589 transmit_response(p, "200 OK", req); 15590 if (option_debug) 15591 ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n"); 15592 return 0; 15593 } 15594 15595 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 15596 update_call_counter(p, DEC_CALL_LIMIT); 15597 15598 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 15599 if (p->owner) 15600 ast_queue_hangup(p->owner); 15601 else 15602 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15603 if (p->initreq.len > 0) { 15604 struct sip_pkt *pkt, *prev_pkt; 15605 /* If the CANCEL we are receiving is a retransmission, and we already have scheduled 15606 * a reliable 487, then we don't want to schedule another one on top of the previous 15607 * one. 15608 * 15609 * As odd as this may sound, we can't rely on the previously-transmitted "reliable" 15610 * response in this situation. What if we've sent all of our reliable responses 15611 * already and now all of a sudden, we get this second CANCEL? 15612 * 15613 * The only way to do this correctly is to cancel our previously-scheduled reliably- 15614 * transmitted response and send a new one in its place. 15615 */ 15616 for (pkt = p->packets, prev_pkt = NULL; pkt; prev_pkt = pkt, pkt = pkt->next) { 15617 if (pkt->seqno == p->lastinvite && pkt->response_code == 487) { 15618 AST_SCHED_DEL(sched, pkt->retransid); 15619 UNLINK(pkt, p->packets, prev_pkt); 15620 ast_free(pkt); 15621 break; 15622 } 15623 } 15624 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 15625 transmit_response(p, "200 OK", req); 15626 return 1; 15627 } else { 15628 transmit_response(p, "481 Call Leg Does Not Exist", req); 15629 return 0; 15630 } 15631 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 11667 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().
11668 { 11669 char buf[1024]; 11670 unsigned int event; 11671 const char *c = get_header(req, "Content-Type"); 11672 11673 /* Need to check the media/type */ 11674 if (!strcasecmp(c, "application/dtmf-relay") || 11675 !strcasecmp(c, "application/DTMF") || 11676 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 11677 unsigned int duration = 0; 11678 11679 /* Try getting the "signal=" part */ 11680 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 11681 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 11682 transmit_response(p, "200 OK", req); /* Should return error */ 11683 return; 11684 } else { 11685 ast_copy_string(buf, c, sizeof(buf)); 11686 } 11687 11688 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 11689 duration = atoi(c); 11690 if (!duration) 11691 duration = 100; /* 100 ms */ 11692 11693 if (!p->owner) { /* not a PBX call */ 11694 transmit_response(p, "481 Call leg/transaction does not exist", req); 11695 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11696 return; 11697 } 11698 11699 if (ast_strlen_zero(buf)) { 11700 transmit_response(p, "200 OK", req); 11701 return; 11702 } 11703 11704 if (buf[0] == '*') 11705 event = 10; 11706 else if (buf[0] == '#') 11707 event = 11; 11708 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 11709 event = 12 + buf[0] - 'A'; 11710 else 11711 event = atoi(buf); 11712 if (event == 16) { 11713 /* send a FLASH event */ 11714 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 11715 ast_queue_frame(p->owner, &f); 11716 if (sipdebug) 11717 ast_verbose("* DTMF-relay event received: FLASH\n"); 11718 } else { 11719 /* send a DTMF event */ 11720 struct ast_frame f = { AST_FRAME_DTMF, }; 11721 if (event < 10) { 11722 f.subclass = '0' + event; 11723 } else if (event < 11) { 11724 f.subclass = '*'; 11725 } else if (event < 12) { 11726 f.subclass = '#'; 11727 } else if (event < 16) { 11728 f.subclass = 'A' + (event - 12); 11729 } 11730 f.len = duration; 11731 ast_queue_frame(p->owner, &f); 11732 if (sipdebug) 11733 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 11734 } 11735 transmit_response(p, "200 OK", req); 11736 return; 11737 } else if (!strcasecmp(c, "application/media_control+xml")) { 11738 /* Eh, we'll just assume it's a fast picture update for now */ 11739 if (p->owner) 11740 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 11741 transmit_response(p, "200 OK", req); 11742 return; 11743 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 11744 /* Client code (from SNOM phone) */ 11745 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 11746 if (p->owner && p->owner->cdr) 11747 ast_cdr_setuserfield(p->owner, c); 11748 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 11749 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 11750 transmit_response(p, "200 OK", req); 11751 } else { 11752 transmit_response(p, "403 Unauthorized", req); 11753 } 11754 return; 11755 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 11756 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 11757 transmit_response(p, "200 OK", req); 11758 return; 11759 } 11760 11761 /* Other type of INFO message, not really understood by Asterisk */ 11762 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 11763 11764 /* Nothing in the header is interesting, now check if content-length is 0 */ 11765 if (!strcasecmp(get_header(req, "Content-Length"), "0")) { 11766 transmit_response(p, "200 OK", req); 11767 return; 11768 } /* else ... there issomething in the message body, do something with it if you need to */ 11769 11770 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 11771 transmit_response(p, "415 Unsupported media type", req); 11772 return; 11773 }
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 14544 of file chan_sip.c.
References __sip_ack(), ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_clear_flag, AST_CONTROL_BUSY, AST_CONTROL_UNHOLD, 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_set_alt_peer(), 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(), FLAG_RESPONSE, sip_pvt::flags, get_destination(), get_header(), get_ip_and_port_from_sdp(), get_rdnis(), get_sip_pvt_byid_locked(), sip_pvt::glareinvite, handle_invite_replaces(), ast_channel::hangupcause, sip_request::headers, INC_CALL_LIMIT, sip_pvt::initreq, INV_COMPLETED, INV_CONFIRMED, 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::peername, sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_request::rlPart2, sip_pvt::rtp, S_OR, SDP_AUDIO, SDP_VIDEO, 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, sip_pvt::vrtp, XMIT_CRITICAL, XMIT_RELIABLE, and XMIT_UNRELIABLE.
Referenced by handle_request().
14545 { 14546 int res = 1; 14547 int gotdest; 14548 const char *p_replaces; 14549 char *replace_id = NULL; 14550 const char *required; 14551 unsigned int required_profile = 0; 14552 struct ast_channel *c = NULL; /* New channel */ 14553 int reinvite = 0; 14554 14555 /* Find out what they support */ 14556 if (!p->sipoptions) { 14557 const char *supported = get_header(req, "Supported"); 14558 if (!ast_strlen_zero(supported)) 14559 parse_sip_options(p, supported); 14560 } 14561 14562 /* Find out what they require */ 14563 required = get_header(req, "Require"); 14564 if (!ast_strlen_zero(required)) { 14565 required_profile = parse_sip_options(NULL, required); 14566 if (required_profile && required_profile != SIP_OPT_REPLACES) { 14567 /* At this point we only support REPLACES */ 14568 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 14569 ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required); 14570 p->invitestate = INV_COMPLETED; 14571 if (!p->lastinvite) 14572 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14573 return -1; 14574 } 14575 } 14576 14577 /* Check if this is a loop */ 14578 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->invitestate != INV_TERMINATED && p->invitestate != INV_CONFIRMED)) { 14579 /* This is a call to ourself. Send ourselves an error code and stop 14580 processing immediately, as SIP really has no good mechanism for 14581 being able to call yourself */ 14582 /* If pedantic is on, we need to check the tags. If they're different, this is 14583 in fact a forked call through a SIP proxy somewhere. */ 14584 int different; 14585 if (pedanticsipchecking) 14586 different = sip_uri_cmp(p->initreq.rlPart2, req->rlPart2); 14587 else 14588 different = strcmp(p->initreq.rlPart2, req->rlPart2); 14589 if (!different) { 14590 transmit_response(p, "482 Loop Detected", req); 14591 p->invitestate = INV_COMPLETED; 14592 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14593 return 0; 14594 } else { 14595 /* This is a spiral. What we need to do is to just change the outgoing INVITE 14596 * so that it now routes to the new Request URI. Since we created the INVITE ourselves 14597 * that should be all we need to do. 14598 */ 14599 char *uri = ast_strdupa(req->rlPart2); 14600 char *at = strchr(uri, '@'); 14601 char *peerorhost; 14602 if (option_debug > 2) { 14603 ast_log(LOG_DEBUG, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", p->initreq.rlPart2, req->rlPart2); 14604 } 14605 if (at) { 14606 *at = '\0'; 14607 } 14608 /* Parse out "sip:" */ 14609 if ((peerorhost = strchr(uri, ':'))) { 14610 *peerorhost++ = '\0'; 14611 } 14612 ast_string_field_free(p, theirtag); 14613 /* Treat this as if there were a call forward instead... 14614 */ 14615 ast_string_field_set(p->owner, call_forward, peerorhost); 14616 ast_queue_control(p->owner, AST_CONTROL_BUSY); 14617 return 0; 14618 } 14619 } 14620 14621 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) { 14622 if (!ast_test_flag(&p->flags[0], SIP_OUTGOING) && ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) { 14623 /* We have received a reINVITE on an incoming call to which we have sent a 200 OK but not yet received 14624 * an ACK. According to RFC 5407, Section 3.1.4, the proper way to handle this race condition is to accept 14625 * the reINVITE since we have established a dialog. 14626 */ 14627 14628 /* Note that this will both clear the pendinginvite flag and cancel the 14629 * retransmission of the 200 OK. Basically, we're accepting this reINVITE as both an ACK 14630 * and a reINVITE in one request. 14631 */ 14632 __sip_ack(p, p->lastinvite, FLAG_RESPONSE, 0); 14633 } else { 14634 /* We already have a pending invite. Sorry. You are on hold. */ 14635 p->glareinvite = seqno; 14636 if (p->rtp && find_sdp(req)) { 14637 struct sockaddr_in sin; 14638 if (get_ip_and_port_from_sdp(req, SDP_AUDIO, &sin)) { 14639 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Audio may not work properly on this call.\n"); 14640 } else { 14641 ast_rtp_set_alt_peer(p->rtp, &sin); 14642 } 14643 if (p->vrtp) { 14644 if (get_ip_and_port_from_sdp(req, SDP_VIDEO, &sin)) { 14645 ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Video may not work properly on this call.\n"); 14646 } else { 14647 ast_rtp_set_alt_peer(p->vrtp, &sin); 14648 } 14649 } 14650 } 14651 transmit_response_reliable(p, "491 Request Pending", req); 14652 if (option_debug) 14653 ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 14654 /* Don't destroy dialog here */ 14655 return 0; 14656 } 14657 } 14658 14659 p_replaces = get_header(req, "Replaces"); 14660 if (!ast_strlen_zero(p_replaces)) { 14661 /* We have a replaces header */ 14662 char *ptr; 14663 char *fromtag = NULL; 14664 char *totag = NULL; 14665 char *start, *to; 14666 int error = 0; 14667 14668 if (p->owner) { 14669 if (option_debug > 2) 14670 ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 14671 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 14672 /* Do not destroy existing call */ 14673 return -1; 14674 } 14675 14676 if (sipdebug && option_debug > 2) 14677 ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 14678 /* Create a buffer we can manipulate */ 14679 replace_id = ast_strdupa(p_replaces); 14680 ast_uri_decode(replace_id); 14681 14682 if (!p->refer && !sip_refer_allocate(p)) { 14683 transmit_response_reliable(p, "500 Server Internal Error", req); 14684 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 14685 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14686 p->invitestate = INV_COMPLETED; 14687 return -1; 14688 } 14689 14690 /* Todo: (When we find phones that support this) 14691 if the replaces header contains ";early-only" 14692 we can only replace the call in early 14693 stage, not after it's up. 14694 14695 If it's not in early mode, 486 Busy. 14696 */ 14697 14698 /* Skip leading whitespace */ 14699 replace_id = ast_skip_blanks(replace_id); 14700 14701 start = replace_id; 14702 while ( (ptr = strsep(&start, ";")) ) { 14703 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 14704 if ( (to = strcasestr(ptr, "to-tag=") ) ) 14705 totag = to + 7; /* skip the keyword */ 14706 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 14707 fromtag = to + 9; /* skip the keyword */ 14708 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 14709 } 14710 } 14711 14712 if (sipdebug && option_debug > 3) 14713 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>"); 14714 14715 14716 /* Try to find call that we are replacing 14717 If we have a Replaces header, we need to cancel that call if we succeed with this call 14718 */ 14719 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 14720 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 14721 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req); 14722 error = 1; 14723 } 14724 14725 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 14726 14727 /* The matched call is the call from the transferer to Asterisk . 14728 We want to bridge the bridged part of the call to the 14729 incoming invite, thus taking over the refered call */ 14730 14731 if (p->refer->refer_call == p) { 14732 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 14733 p->refer->refer_call = NULL; 14734 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 14735 error = 1; 14736 } 14737 14738 if (!error && !p->refer->refer_call->owner) { 14739 /* Oops, someting wrong anyway, no owner, no call */ 14740 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 14741 /* Check for better return code */ 14742 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req); 14743 error = 1; 14744 } 14745 14746 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 ) { 14747 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 14748 transmit_response_reliable(p, "603 Declined (Replaces)", req); 14749 error = 1; 14750 } 14751 14752 if (error) { /* Give up this dialog */ 14753 append_history(p, "Xfer", "INVITE/Replace Failed."); 14754 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14755 ast_mutex_unlock(&p->lock); 14756 if (p->refer->refer_call) { 14757 ast_mutex_unlock(&p->refer->refer_call->lock); 14758 if (p->refer->refer_call->owner) { 14759 ast_channel_unlock(p->refer->refer_call->owner); 14760 } 14761 } 14762 p->invitestate = INV_COMPLETED; 14763 return -1; 14764 } 14765 } 14766 14767 14768 /* Check if this is an INVITE that sets up a new dialog or 14769 a re-invite in an existing dialog */ 14770 14771 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14772 int newcall = (p->initreq.headers ? TRUE : FALSE); 14773 14774 if (sip_cancel_destroy(p)) 14775 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 14776 /* This also counts as a pending invite */ 14777 p->pendinginvite = seqno; 14778 check_via(p, req); 14779 14780 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 14781 if (!p->owner) { /* Not a re-invite */ 14782 if (debug) 14783 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 14784 if (newcall) 14785 append_history(p, "Invite", "New call: %s", p->callid); 14786 parse_ok_contact(p, req); 14787 } else { /* Re-invite on existing call */ 14788 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 14789 /* Handle SDP here if we already have an owner */ 14790 if (find_sdp(req)) { 14791 if (process_sdp(p, req)) { 14792 transmit_response_reliable(p, "488 Not acceptable here", req); 14793 if (!p->lastinvite) 14794 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14795 return -1; 14796 } 14797 } else { 14798 p->jointcapability = p->capability; 14799 if (option_debug > 2) 14800 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 14801 /* Some devices signal they want to be put off hold by sending a re-invite 14802 *without* an SDP, which is supposed to mean "Go back to your state" 14803 and since they put os on remote hold, we go back to off hold */ 14804 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 14805 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 14806 /* Activate a re-invite */ 14807 ast_queue_frame(p->owner, &ast_null_frame); 14808 change_hold_state(p, req, FALSE, 0); 14809 } 14810 } 14811 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */ 14812 append_history(p, "ReInv", "Re-invite received"); 14813 } 14814 } else if (debug) 14815 ast_verbose("Ignoring this INVITE request\n"); 14816 14817 14818 if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) { 14819 /* This is a new invite */ 14820 /* Handle authentication if this is our first invite */ 14821 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 14822 if (res == AUTH_CHALLENGE_SENT) { 14823 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 14824 return 0; 14825 } 14826 if (res < 0) { /* Something failed in authentication */ 14827 if (res == AUTH_FAKE_AUTH) { 14828 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 14829 transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE); 14830 } else { 14831 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 14832 transmit_response_reliable(p, "403 Forbidden", req); 14833 } 14834 p->invitestate = INV_COMPLETED; 14835 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14836 ast_string_field_free(p, theirtag); 14837 return 0; 14838 } 14839 14840 /* We have a succesful authentication, process the SDP portion if there is one */ 14841 if (find_sdp(req)) { 14842 if (process_sdp(p, req)) { 14843 /* Unacceptable codecs */ 14844 transmit_response_reliable(p, "488 Not acceptable here", req); 14845 p->invitestate = INV_COMPLETED; 14846 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14847 if (option_debug) 14848 ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); 14849 return -1; 14850 } 14851 } else { /* No SDP in invite, call control session */ 14852 p->jointcapability = p->capability; 14853 if (option_debug > 1) 14854 ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n"); 14855 } 14856 14857 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 14858 /* This seems redundant ... see !p-owner above */ 14859 if (p->owner) 14860 ast_queue_frame(p->owner, &ast_null_frame); 14861 14862 14863 /* Initialize the context if it hasn't been already */ 14864 if (ast_strlen_zero(p->context)) 14865 ast_string_field_set(p, context, default_context); 14866 14867 14868 /* Check number of concurrent calls -vs- incoming limit HERE */ 14869 if (option_debug) 14870 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 14871 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 14872 if (res < 0) { 14873 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 14874 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 14875 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14876 p->invitestate = INV_COMPLETED; 14877 } 14878 return 0; 14879 } 14880 gotdest = get_destination(p, NULL); /* Get destination right away */ 14881 get_rdnis(p, NULL); /* Get redirect information */ 14882 extract_uri(p, req); /* Get the Contact URI */ 14883 build_contact(p); /* Build our contact header */ 14884 14885 if (p->rtp) { 14886 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 14887 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 14888 } 14889 14890 if (!replace_id && gotdest) { /* No matching extension found */ 14891 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 14892 transmit_response_reliable(p, "484 Address Incomplete", req); 14893 else { 14894 char *decoded_exten = ast_strdupa(p->exten); 14895 14896 transmit_response_reliable(p, "404 Not Found", req); 14897 ast_uri_decode(decoded_exten); 14898 ast_log(LOG_NOTICE, "Call from '%s' to extension" 14899 " '%s' rejected because extension not found.\n", 14900 S_OR(p->username, p->peername), decoded_exten); 14901 } 14902 p->invitestate = INV_COMPLETED; 14903 update_call_counter(p, DEC_CALL_LIMIT); 14904 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14905 return 0; 14906 } else { 14907 /* If no extension was specified, use the s one */ 14908 /* Basically for calling to IP/Host name only */ 14909 if (ast_strlen_zero(p->exten)) 14910 ast_string_field_set(p, exten, "s"); 14911 /* Initialize our tag */ 14912 14913 make_our_tag(p->tag, sizeof(p->tag)); 14914 /* First invitation - create the channel */ 14915 c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL)); 14916 *recount = 1; 14917 14918 /* Save Record-Route for any later requests we make on this dialogue */ 14919 build_route(p, req, 0); 14920 14921 if (c) { 14922 /* Pre-lock the call */ 14923 ast_channel_lock(c); 14924 } 14925 } 14926 } else { 14927 if (option_debug > 1 && sipdebug) { 14928 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 14929 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 14930 else 14931 ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 14932 } 14933 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 14934 reinvite = 1; 14935 c = p->owner; 14936 } 14937 14938 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 14939 p->lastinvite = seqno; 14940 14941 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 14942 /* Go and take over the target call */ 14943 if (sipdebug && option_debug > 3) 14944 ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid); 14945 return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin); 14946 } 14947 14948 14949 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 14950 enum ast_channel_state c_state = c->_state; 14951 14952 if (c_state != AST_STATE_UP && reinvite && 14953 (p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) { 14954 /* If these conditions are true, and the channel is still in the 'ringing' 14955 * state, then this likely means that we have a situation where the initial 14956 * INVITE transaction has completed *but* the channel's state has not yet been 14957 * changed to UP. The reason this could happen is if the reinvite is received 14958 * on the SIP socket prior to an application calling ast_read on this channel 14959 * to read the answer frame we earlier queued on it. In this case, the reinvite 14960 * is completely legitimate so we need to handle this the same as if the channel 14961 * were already UP. Thus we are purposely falling through to the AST_STATE_UP case. 14962 */ 14963 c_state = AST_STATE_UP; 14964 } 14965 14966 switch(c_state) { 14967 case AST_STATE_DOWN: 14968 if (option_debug > 1) 14969 ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name); 14970 transmit_response(p, "100 Trying", req); 14971 p->invitestate = INV_PROCEEDING; 14972 ast_setstate(c, AST_STATE_RING); 14973 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 14974 enum ast_pbx_result res; 14975 14976 res = ast_pbx_start(c); 14977 14978 switch(res) { 14979 case AST_PBX_FAILED: 14980 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 14981 p->invitestate = INV_COMPLETED; 14982 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14983 transmit_response(p, "503 Unavailable", req); 14984 else 14985 transmit_response_reliable(p, "503 Unavailable", req); 14986 break; 14987 case AST_PBX_CALL_LIMIT: 14988 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 14989 p->invitestate = INV_COMPLETED; 14990 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14991 transmit_response(p, "480 Temporarily Unavailable", req); 14992 else 14993 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 14994 break; 14995 case AST_PBX_SUCCESS: 14996 /* nothing to do */ 14997 break; 14998 } 14999 15000 if (res) { 15001 15002 /* Unlock locks so ast_hangup can do its magic */ 15003 ast_mutex_unlock(&c->lock); 15004 ast_mutex_unlock(&p->lock); 15005 ast_hangup(c); 15006 ast_mutex_lock(&p->lock); 15007 c = NULL; 15008 } 15009 } else { /* Pickup call in call group */ 15010 ast_channel_unlock(c); 15011 *nounlock = 1; 15012 if (ast_pickup_call(c)) { 15013 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 15014 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15015 transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */ 15016 else 15017 transmit_response_reliable(p, "503 Unavailable", req); 15018 sip_alreadygone(p); 15019 /* Unlock locks so ast_hangup can do its magic */ 15020 ast_mutex_unlock(&p->lock); 15021 c->hangupcause = AST_CAUSE_CALL_REJECTED; 15022 } else { 15023 ast_mutex_unlock(&p->lock); 15024 ast_setstate(c, AST_STATE_DOWN); 15025 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 15026 } 15027 p->invitestate = INV_COMPLETED; 15028 ast_hangup(c); 15029 ast_mutex_lock(&p->lock); 15030 c = NULL; 15031 } 15032 break; 15033 case AST_STATE_RING: 15034 transmit_response(p, "100 Trying", req); 15035 p->invitestate = INV_PROCEEDING; 15036 break; 15037 case AST_STATE_RINGING: 15038 transmit_response(p, "180 Ringing", req); 15039 p->invitestate = INV_PROCEEDING; 15040 break; 15041 case AST_STATE_UP: 15042 if (option_debug > 1) 15043 ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); 15044 15045 transmit_response(p, "100 Trying", req); 15046 15047 if (p->t38.state == T38_PEER_REINVITE) { 15048 struct ast_channel *bridgepeer = NULL; 15049 struct sip_pvt *bridgepvt = NULL; 15050 15051 if ((bridgepeer = ast_bridged_channel(p->owner))) { 15052 /* 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*/ 15053 /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */ 15054 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 15055 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 15056 if (bridgepvt->t38.state == T38_DISABLED) { 15057 if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */ 15058 /* Send re-invite to the bridged channel */ 15059 sip_handle_t38_reinvite(bridgepeer, p, 1); 15060 } else { /* Something is wrong with peers udptl struct */ 15061 ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n"); 15062 ast_mutex_lock(&bridgepvt->lock); 15063 bridgepvt->t38.state = T38_DISABLED; 15064 ast_mutex_unlock(&bridgepvt->lock); 15065 if (option_debug > 1) 15066 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name); 15067 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15068 transmit_response(p, "488 Not acceptable here", req); 15069 else 15070 transmit_response_reliable(p, "488 Not acceptable here", req); 15071 15072 } 15073 } else { 15074 /* The other side is already setup for T.38 most likely so we need to acknowledge this too */ 15075 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15076 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 15077 p->t38.state = T38_ENABLED; 15078 if (option_debug) 15079 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 15080 } 15081 } else { 15082 /* Other side is not a SIP channel */ 15083 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15084 transmit_response(p, "488 Not acceptable here", req); 15085 else 15086 transmit_response_reliable(p, "488 Not acceptable here", req); 15087 p->t38.state = T38_DISABLED; 15088 if (option_debug > 1) 15089 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 15090 15091 if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */ 15092 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15093 } 15094 } else { 15095 /* we are not bridged in a call */ 15096 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15097 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 15098 p->t38.state = T38_ENABLED; 15099 if (option_debug) 15100 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 15101 } 15102 } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */ 15103 /* If this is not a re-invite or something to ignore - it's critical */ 15104 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15105 transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_CRITICAL))); 15106 } 15107 p->invitestate = INV_TERMINATED; 15108 break; 15109 default: 15110 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 15111 transmit_response(p, "100 Trying", req); 15112 break; 15113 } 15114 } else { 15115 if (p && (p->autokillid == -1)) { 15116 const char *msg; 15117 15118 if (!p->jointcapability) 15119 msg = "488 Not Acceptable Here (codec error)"; 15120 else { 15121 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 15122 msg = "503 Unavailable"; 15123 } 15124 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15125 transmit_response(p, msg, req); 15126 else 15127 transmit_response_reliable(p, msg, req); 15128 p->invitestate = INV_COMPLETED; 15129 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15130 } 15131 } 15132 return res; 15133 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 15778 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().
15779 { 15780 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 15781 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15782 ast_verbose("Receiving message!\n"); 15783 receive_message(p, req); 15784 } else 15785 transmit_response(p, "202 Accepted", req); 15786 return 1; 15787 }
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 13927 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().
13928 { 13929 /* This is mostly a skeleton for future improvements */ 13930 /* Mostly created to return proper answers on notifications on outbound REFER's */ 13931 int res = 0; 13932 const char *event = get_header(req, "Event"); 13933 char *eventid = NULL; 13934 char *sep; 13935 13936 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 13937 *sep++ = '\0'; 13938 eventid = sep; 13939 } 13940 13941 if (option_debug > 1 && sipdebug) 13942 ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event); 13943 13944 if (strcmp(event, "refer")) { 13945 /* We don't understand this event. */ 13946 /* Here's room to implement incoming voicemail notifications :-) */ 13947 transmit_response(p, "489 Bad event", req); 13948 res = -1; 13949 } else { 13950 /* Save nesting depth for now, since there might be other events we will 13951 support in the future */ 13952 13953 /* Handle REFER notifications */ 13954 13955 char buf[1024]; 13956 char *cmd, *code; 13957 int respcode; 13958 int success = TRUE; 13959 13960 /* EventID for each transfer... EventID is basically the REFER cseq 13961 13962 We are getting notifications on a call that we transfered 13963 We should hangup when we are getting a 200 OK in a sipfrag 13964 Check if we have an owner of this event */ 13965 13966 /* Check the content type */ 13967 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 13968 /* We need a sipfrag */ 13969 transmit_response(p, "400 Bad request", req); 13970 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13971 return -1; 13972 } 13973 13974 /* Get the text of the attachment */ 13975 if (get_msg_text(buf, sizeof(buf), req)) { 13976 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 13977 transmit_response(p, "400 Bad request", req); 13978 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13979 return -1; 13980 } 13981 13982 /* 13983 From the RFC... 13984 A minimal, but complete, implementation can respond with a single 13985 NOTIFY containing either the body: 13986 SIP/2.0 100 Trying 13987 13988 if the subscription is pending, the body: 13989 SIP/2.0 200 OK 13990 if the reference was successful, the body: 13991 SIP/2.0 503 Service Unavailable 13992 if the reference failed, or the body: 13993 SIP/2.0 603 Declined 13994 13995 if the REFER request was accepted before approval to follow the 13996 reference could be obtained and that approval was subsequently denied 13997 (see Section 2.4.7). 13998 13999 If there are several REFERs in the same dialog, we need to 14000 match the ID of the event header... 14001 */ 14002 if (option_debug > 2) 14003 ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 14004 cmd = ast_skip_blanks(buf); 14005 code = cmd; 14006 /* We are at SIP/2.0 */ 14007 while(*code && (*code > 32)) { /* Search white space */ 14008 code++; 14009 } 14010 *code++ = '\0'; 14011 code = ast_skip_blanks(code); 14012 sep = code; 14013 sep++; 14014 while(*sep && (*sep > 32)) { /* Search white space */ 14015 sep++; 14016 } 14017 *sep++ = '\0'; /* Response string */ 14018 respcode = atoi(code); 14019 switch (respcode) { 14020 case 100: /* Trying: */ 14021 case 101: /* dialog establishment */ 14022 /* Don't do anything yet */ 14023 break; 14024 case 183: /* Ringing: */ 14025 /* Don't do anything yet */ 14026 break; 14027 case 200: /* OK: The new call is up, hangup this call */ 14028 /* Hangup the call that we are replacing */ 14029 break; 14030 case 301: /* Moved permenantly */ 14031 case 302: /* Moved temporarily */ 14032 /* Do we get the header in the packet in this case? */ 14033 success = FALSE; 14034 break; 14035 case 503: /* Service Unavailable: The new call failed */ 14036 /* Cancel transfer, continue the call */ 14037 success = FALSE; 14038 break; 14039 case 603: /* Declined: Not accepted */ 14040 /* Cancel transfer, continue the current call */ 14041 success = FALSE; 14042 break; 14043 } 14044 if (!success) { 14045 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 14046 } 14047 14048 /* Confirm that we received this packet */ 14049 transmit_response(p, "200 OK", req); 14050 }; 14051 14052 if (!p->lastinvite) 14053 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14054 14055 return res; 14056 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming OPTIONS request.
Definition at line 14059 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().
14060 { 14061 int res; 14062 14063 14064 /* XXX Should we authenticate OPTIONS? XXX */ 14065 14066 if (p->lastinvite) { 14067 /* if this is a request in an active dialog, just confirm that the dialog exists. */ 14068 transmit_response_with_allow(p, "200 OK", req, 0); 14069 return 0; 14070 } 14071 14072 res = get_destination(p, req); 14073 build_contact(p); 14074 14075 if (ast_strlen_zero(p->context)) 14076 ast_string_field_set(p, context, default_context); 14077 14078 if (ast_shutting_down()) 14079 transmit_response_with_allow(p, "503 Unavailable", req, 0); 14080 else if (res < 0) 14081 transmit_response_with_allow(p, "404 Not Found", req, 0); 14082 else 14083 transmit_response_with_allow(p, "200 OK", req, 0); 14084 14085 /* Destroy if this OPTIONS was the opening request, but not if 14086 it's in the middle of a normal call flow. */ 14087 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14088 14089 return res; 14090 }
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 15300 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().
15301 { 15302 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 15303 /* Chan2: Call between asterisk and transferee */ 15304 15305 int res = 0; 15306 15307 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15308 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"); 15309 15310 if (!p->owner) { 15311 /* This is a REFER outside of an existing SIP dialog */ 15312 /* We can't handle that, so decline it */ 15313 if (option_debug > 2) 15314 ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 15315 transmit_response(p, "603 Declined (No dialog)", req); 15316 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 15317 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 15318 sip_alreadygone(p); 15319 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15320 } 15321 return 0; 15322 } 15323 15324 15325 /* Check if transfer is allowed from this device */ 15326 if (p->allowtransfer == TRANSFER_CLOSED ) { 15327 /* Transfer not allowed, decline */ 15328 transmit_response(p, "603 Declined (policy)", req); 15329 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 15330 /* Do not destroy SIP session */ 15331 return 0; 15332 } 15333 15334 if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 15335 /* Already have a pending REFER */ 15336 transmit_response(p, "491 Request pending", req); 15337 append_history(p, "Xfer", "Refer failed. Request pending."); 15338 return 0; 15339 } 15340 15341 /* Allocate memory for call transfer data */ 15342 if (!p->refer && !sip_refer_allocate(p)) { 15343 transmit_response(p, "500 Internal Server Error", req); 15344 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 15345 return -3; 15346 } 15347 15348 res = get_refer_info(p, req); /* Extract headers */ 15349 15350 p->refer->status = REFER_SENT; 15351 15352 if (res != 0) { 15353 switch (res) { 15354 case -2: /* Syntax error */ 15355 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 15356 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 15357 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 15358 ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 15359 break; 15360 case -3: 15361 transmit_response(p, "603 Declined (Non sip: uri)", req); 15362 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 15363 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 15364 ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n"); 15365 break; 15366 default: 15367 /* Refer-to extension not found, fake a failed transfer */ 15368 transmit_response(p, "202 Accepted", req); 15369 append_history(p, "Xfer", "Refer failed. Bad extension."); 15370 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 15371 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15372 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 15373 ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 15374 break; 15375 } 15376 return 0; 15377 } 15378 if (ast_strlen_zero(p->context)) 15379 ast_string_field_set(p, context, default_context); 15380 15381 /* If we do not support SIP domains, all transfers are local */ 15382 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 15383 p->refer->localtransfer = 1; 15384 if (sipdebug && option_debug > 2) 15385 ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 15386 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 15387 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 15388 p->refer->localtransfer = 1; 15389 } else if (sipdebug && option_debug > 2) 15390 ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 15391 15392 /* Is this a repeat of a current request? Ignore it */ 15393 /* Don't know what else to do right now. */ 15394 if (ignore) 15395 return res; 15396 15397 /* If this is a blind transfer, we have the following 15398 channels to work with: 15399 - chan1, chan2: The current call between transferer and transferee (2 channels) 15400 - target_channel: A new call from the transferee to the target (1 channel) 15401 We need to stay tuned to what happens in order to be able 15402 to bring back the call to the transferer */ 15403 15404 /* If this is a attended transfer, we should have all call legs within reach: 15405 - chan1, chan2: The call between the transferer and transferee (2 channels) 15406 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 15407 We want to bridge chan2 with targetcall_pvt! 15408 15409 The replaces call id in the refer message points 15410 to the call leg between Asterisk and the transferer. 15411 So we need to connect the target and the transferee channel 15412 and hangup the two other channels silently 15413 15414 If the target is non-local, the call ID could be on a remote 15415 machine and we need to send an INVITE with replaces to the 15416 target. We basically handle this as a blind transfer 15417 and let the sip_call function catch that we need replaces 15418 header in the INVITE. 15419 */ 15420 15421 15422 /* Get the transferer's channel */ 15423 current.chan1 = p->owner; 15424 15425 /* Find the other part of the bridge (2) - transferee */ 15426 current.chan2 = ast_bridged_channel(current.chan1); 15427 15428 if (sipdebug && option_debug > 2) 15429 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>"); 15430 15431 if (!current.chan2 && !p->refer->attendedtransfer) { 15432 /* No bridged channel, propably IVR or echo or similar... */ 15433 /* Guess we should masquerade or something here */ 15434 /* Until we figure it out, refuse transfer of such calls */ 15435 if (sipdebug && option_debug > 2) 15436 ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n"); 15437 p->refer->status = REFER_FAILED; 15438 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 15439 transmit_response(p, "603 Declined", req); 15440 return -1; 15441 } 15442 15443 if (current.chan2) { 15444 if (sipdebug && option_debug > 3) 15445 ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 15446 15447 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 15448 } 15449 15450 ast_set_flag(&p->flags[0], SIP_GOTREFER); 15451 15452 /* Attended transfer: Find all call legs and bridge transferee with target*/ 15453 if (p->refer->attendedtransfer) { 15454 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 15455 return res; /* We're done with the transfer */ 15456 /* Fall through for remote transfers that we did not find locally */ 15457 if (sipdebug && option_debug > 3) 15458 ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 15459 /* Fallthrough if we can't find the call leg internally */ 15460 } 15461 15462 15463 /* Parking a call */ 15464 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 15465 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 15466 *nounlock = 1; 15467 ast_channel_unlock(current.chan1); 15468 copy_request(¤t.req, req); 15469 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15470 p->refer->status = REFER_200OK; 15471 append_history(p, "Xfer", "REFER to call parking."); 15472 if (sipdebug && option_debug > 3) 15473 ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 15474 sip_park(current.chan2, current.chan1, req, seqno); 15475 return res; 15476 } 15477 15478 /* Blind transfers and remote attended xfers */ 15479 transmit_response(p, "202 Accepted", req); 15480 15481 if (current.chan1 && current.chan2) { 15482 if (option_debug > 2) 15483 ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name); 15484 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 15485 } 15486 if (current.chan2) { 15487 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 15488 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 15489 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 15490 /* One for the new channel */ 15491 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 15492 /* Attended transfer to remote host, prepare headers for the INVITE */ 15493 if (p->refer->referred_by) 15494 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 15495 } 15496 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 15497 if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) { 15498 char tempheader[SIPBUFSIZE]; 15499 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 15500 p->refer->replaces_callid_totag ? ";to-tag=" : "", 15501 p->refer->replaces_callid_totag, 15502 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 15503 p->refer->replaces_callid_fromtag); 15504 if (current.chan2) 15505 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 15506 } 15507 /* Must release lock now, because it will not longer 15508 be accessible after the transfer! */ 15509 *nounlock = 1; 15510 ast_channel_unlock(current.chan1); 15511 15512 /* Connect the call */ 15513 15514 /* FAKE ringing if not attended transfer */ 15515 if (!p->refer->attendedtransfer) 15516 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 15517 15518 /* For blind transfer, this will lead to a new call */ 15519 /* For attended transfer to remote host, this will lead to 15520 a new SIP call with a replaces header, if the dial plan allows it 15521 */ 15522 if (!current.chan2) { 15523 /* We have no bridge, so we're talking with Asterisk somehow */ 15524 /* We need to masquerade this call */ 15525 /* What to do to fix this situation: 15526 * Set up the new call in a new channel 15527 * Let the new channel masq into this channel 15528 Please add that code here :-) 15529 */ 15530 p->refer->status = REFER_FAILED; 15531 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 15532 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15533 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 15534 return -1; 15535 } 15536 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 15537 15538 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 15539 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 15540 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 15541 15542 if (!res) { 15543 /* Success - we have a new channel */ 15544 if (option_debug > 2) 15545 ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 15546 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 15547 if (p->refer->localtransfer) 15548 p->refer->status = REFER_200OK; 15549 if (p->owner) 15550 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 15551 append_history(p, "Xfer", "Refer succeeded."); 15552 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15553 /* Do not hangup call, the other side do that when we say 200 OK */ 15554 /* We could possibly implement a timer here, auto congestion */ 15555 res = 0; 15556 } else { 15557 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 15558 if (option_debug > 2) 15559 ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 15560 append_history(p, "Xfer", "Refer failed."); 15561 /* Failure of some kind */ 15562 p->refer->status = REFER_FAILED; 15563 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 15564 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15565 res = -1; 15566 } 15567 return res; 15568 }
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 16094 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().
16095 { 16096 enum check_auth_result res; 16097 16098 /* Use this as the basis */ 16099 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16100 ast_verbose("Using latest REGISTER request as basis request\n"); 16101 copy_request(&p->initreq, req); 16102 check_via(p, req); 16103 if ((res = register_verify(p, sin, req, e)) < 0) { 16104 const char *reason; 16105 16106 switch (res) { 16107 case AUTH_SECRET_FAILED: 16108 reason = "Wrong password"; 16109 break; 16110 case AUTH_USERNAME_MISMATCH: 16111 reason = "Username/auth name mismatch"; 16112 break; 16113 case AUTH_NOT_FOUND: 16114 reason = "No matching peer found"; 16115 break; 16116 case AUTH_UNKNOWN_DOMAIN: 16117 reason = "Not a local domain"; 16118 break; 16119 case AUTH_PEER_NOT_DYNAMIC: 16120 reason = "Peer is not supposed to register"; 16121 break; 16122 case AUTH_ACL_FAILED: 16123 reason = "Device does not match ACL"; 16124 break; 16125 default: 16126 reason = "Unknown failure"; 16127 break; 16128 } 16129 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 16130 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 16131 reason); 16132 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 16133 } else 16134 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 16135 16136 if (res < 1) { 16137 /* Destroy the session, but keep us around for just a bit in case they don't 16138 get our 200 OK */ 16139 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16140 } 16141 return res; 16142 }
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 15790 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(), build_route(), 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(), TRUE, sip_pvt::useragent, sip_pvt::username, XMIT_UNRELIABLE, and XPIDF_XML.
Referenced by handle_request().
15791 { 15792 int gotdest = 0; 15793 int res = 0; 15794 int firststate = AST_EXTENSION_REMOVED; 15795 struct sip_peer *authpeer = NULL; 15796 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 15797 const char *accept = get_header(req, "Accept"); 15798 int resubscribe = (p->subscribed != NONE); 15799 char *temp, *event; 15800 15801 if (p->initreq.headers) { 15802 /* We already have a dialog */ 15803 if (p->initreq.method != SIP_SUBSCRIBE) { 15804 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 15805 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 15806 transmit_response(p, "403 Forbidden (within dialog)", req); 15807 /* Do not destroy session, since we will break the call if we do */ 15808 if (option_debug) 15809 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); 15810 return 0; 15811 } else if (ast_test_flag(req, SIP_PKT_DEBUG)) { 15812 if (option_debug) { 15813 if (resubscribe) 15814 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 15815 else 15816 ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid); 15817 } 15818 } 15819 } 15820 15821 /* Check if we have a global disallow setting on subscriptions. 15822 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 15823 */ 15824 if (!global_allowsubscribe) { 15825 transmit_response(p, "403 Forbidden (policy)", req); 15826 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15827 return 0; 15828 } 15829 15830 if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */ 15831 const char *to = get_header(req, "To"); 15832 char totag[128]; 15833 15834 /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */ 15835 if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) { 15836 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15837 ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n"); 15838 transmit_response(p, "481 Subscription does not exist", req); 15839 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15840 return 0; 15841 } 15842 15843 /* Use this as the basis */ 15844 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15845 ast_verbose("Creating new subscription\n"); 15846 15847 copy_request(&p->initreq, req); 15848 check_via(p, req); 15849 build_route(p, req, 0); 15850 } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE)) 15851 ast_verbose("Ignoring this SUBSCRIBE request\n"); 15852 15853 /* Find parameters to Event: header value and remove them for now */ 15854 if (ast_strlen_zero(eventheader)) { 15855 transmit_response(p, "489 Bad Event", req); 15856 if (option_debug > 1) 15857 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n"); 15858 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15859 return 0; 15860 } 15861 15862 if ( (strchr(eventheader, ';'))) { 15863 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 15864 temp = strchr(event, ';'); 15865 *temp = '\0'; /* Remove any options for now */ 15866 /* We might need to use them later :-) */ 15867 } else 15868 event = (char *) eventheader; /* XXX is this legal ? */ 15869 15870 /* Handle authentication */ 15871 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 15872 /* if an authentication response was sent, we are done here */ 15873 if (res == AUTH_CHALLENGE_SENT) { 15874 if (authpeer) 15875 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15876 return 0; 15877 } 15878 if (res < 0) { 15879 if (res == AUTH_FAKE_AUTH) { 15880 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 15881 transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE); 15882 } else { 15883 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 15884 transmit_response_reliable(p, "403 Forbidden", req); 15885 } 15886 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15887 if (authpeer) 15888 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15889 return 0; 15890 } 15891 15892 /* Check if this user/peer is allowed to subscribe at all */ 15893 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 15894 transmit_response(p, "403 Forbidden (policy)", req); 15895 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15896 if (authpeer) 15897 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15898 return 0; 15899 } 15900 15901 if (strcmp(event, "message-summary")) { 15902 /* Get destination right away */ 15903 gotdest = get_destination(p, NULL); 15904 } 15905 15906 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 15907 parse_ok_contact(p, req); 15908 15909 build_contact(p); 15910 if (gotdest) { 15911 transmit_response(p, "404 Not Found", req); 15912 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15913 if (authpeer) 15914 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15915 return 0; 15916 } 15917 15918 /* Initialize tag for new subscriptions */ 15919 if (ast_strlen_zero(p->tag)) 15920 make_our_tag(p->tag, sizeof(p->tag)); 15921 15922 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 15923 unsigned int pidf_xml; 15924 15925 if (authpeer) /* No need for authpeer here */ 15926 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15927 15928 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 15929 15930 pidf_xml = strstr(accept, "application/pidf+xml") ? 1 : 0; 15931 15932 /* Older versions of Polycom firmware will claim pidf+xml, but really 15933 * they only support xpidf+xml. */ 15934 if (pidf_xml && strstr(p->useragent, "Polycom")) { 15935 p->subscribed = XPIDF_XML; 15936 } else if (pidf_xml) { 15937 p->subscribed = PIDF_XML; /* RFC 3863 format */ 15938 } else if (strstr(accept, "application/dialog-info+xml")) { 15939 p->subscribed = DIALOG_INFO_XML; 15940 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 15941 } else if (strstr(accept, "application/cpim-pidf+xml")) { 15942 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 15943 } else if (strstr(accept, "application/xpidf+xml")) { 15944 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 15945 } else if (ast_strlen_zero(accept)) { 15946 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 15947 transmit_response(p, "489 Bad Event", req); 15948 15949 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 15950 p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 15951 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15952 return 0; 15953 } 15954 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 15955 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 15956 } else { 15957 /* Can't find a format for events that we know about */ 15958 char mybuf[200]; 15959 snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept); 15960 transmit_response(p, mybuf, req); 15961 15962 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 15963 accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 15964 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15965 return 0; 15966 } 15967 } else if (!strcmp(event, "message-summary")) { 15968 if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) { 15969 /* Format requested that we do not support */ 15970 transmit_response(p, "406 Not Acceptable", req); 15971 if (option_debug > 1) 15972 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept); 15973 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15974 if (authpeer) /* No need for authpeer here */ 15975 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15976 return 0; 15977 } 15978 /* Looks like they actually want a mailbox status 15979 This version of Asterisk supports mailbox subscriptions 15980 The subscribed URI needs to exist in the dial plan 15981 In most devices, this is configurable to the voicemailmain extension you use 15982 */ 15983 if (!authpeer || ast_strlen_zero(authpeer->mailbox)) { 15984 transmit_response(p, "404 Not found (no mailbox)", req); 15985 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15986 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 15987 if (authpeer) /* No need for authpeer here */ 15988 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15989 return 0; 15990 } 15991 15992 p->subscribed = MWI_NOTIFICATION; 15993 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 15994 /* We only allow one subscription per peer */ 15995 sip_destroy(authpeer->mwipvt); 15996 authpeer->mwipvt = p; /* Link from peer to pvt */ 15997 p->relatedpeer = ASTOBJ_REF(authpeer); /* Link from pvt to peer */ 15998 } else { /* At this point, Asterisk does not understand the specified event */ 15999 transmit_response(p, "489 Bad Event", req); 16000 if (option_debug > 1) 16001 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 16002 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16003 if (authpeer) /* No need for authpeer here */ 16004 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 16005 return 0; 16006 } 16007 16008 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) { 16009 if (p->stateid > -1) 16010 ast_extension_state_del(p->stateid, cb_extensionstate); 16011 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 16012 } 16013 16014 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 16015 p->lastinvite = seqno; 16016 if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 16017 p->expiry = atoi(get_header(req, "Expires")); 16018 16019 /* check if the requested expiry-time is within the approved limits from sip.conf */ 16020 if (p->expiry > max_expiry) 16021 p->expiry = max_expiry; 16022 if (p->expiry < min_expiry && p->expiry > 0) 16023 p->expiry = min_expiry; 16024 16025 if (sipdebug || option_debug > 1) { 16026 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 16027 ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox); 16028 else 16029 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 16030 } 16031 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 16032 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 16033 if (p->expiry > 0) 16034 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 16035 16036 if (p->subscribed == MWI_NOTIFICATION) { 16037 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 16038 transmit_response(p, "200 OK", req); 16039 if (p->relatedpeer) { /* Send first notification */ 16040 ASTOBJ_WRLOCK(p->relatedpeer); 16041 sip_send_mwi_to_peer(p->relatedpeer, TRUE); 16042 ASTOBJ_UNLOCK(p->relatedpeer); 16043 } 16044 } else { 16045 struct sip_pvt *p_old; 16046 16047 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 16048 16049 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)); 16050 transmit_response(p, "404 Not found", req); 16051 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16052 return 0; 16053 } 16054 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 16055 transmit_response(p, "200 OK", req); 16056 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 16057 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 16058 /* hide the 'complete' exten/context in the refer_to field for later display */ 16059 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 16060 16061 /* remove any old subscription from this peer for the same exten/context, 16062 as the peer has obviously forgotten about it and it's wasteful to wait 16063 for it to expire and send NOTIFY messages to the peer only to have them 16064 ignored (or generate errors) 16065 */ 16066 ast_mutex_lock(&iflock); 16067 for (p_old = iflist; p_old; p_old = p_old->next) { 16068 if (p_old == p) 16069 continue; 16070 if (p_old->initreq.method != SIP_SUBSCRIBE) 16071 continue; 16072 if (p_old->subscribed == NONE) 16073 continue; 16074 ast_mutex_lock(&p_old->lock); 16075 if (!strcmp(p_old->username, p->username)) { 16076 if (!strcmp(p_old->exten, p->exten) && 16077 !strcmp(p_old->context, p->context)) { 16078 ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY); 16079 ast_mutex_unlock(&p_old->lock); 16080 break; 16081 } 16082 } 16083 ast_mutex_unlock(&p_old->lock); 16084 } 16085 ast_mutex_unlock(&iflock); 16086 } 16087 if (!p->expiry) 16088 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16089 } 16090 return 1; 16091 }
static void handle_response | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Handle SIP response in dialogue.
Definition at line 13200 of file chan_sip.c.
References __sip_ack(), __sip_semi_ack(), append_history, 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.
13201 { 13202 struct ast_channel *owner; 13203 int sipmethod; 13204 int res = 1; 13205 int ack_res; 13206 const char *c = get_header(req, "Cseq"); 13207 /* 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 */ 13208 char *c_copy = ast_strdupa(c); 13209 /* Skip the Cseq and its subsequent spaces */ 13210 const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy)); 13211 13212 if (!msg) 13213 msg = ""; 13214 13215 sipmethod = find_sip_method(msg); 13216 13217 owner = p->owner; 13218 if (owner) 13219 owner->hangupcause = hangup_sip2cause(resp); 13220 13221 /* Acknowledge whatever it is destined for */ 13222 if ((resp >= 100) && (resp <= 199)) { 13223 ack_res = __sip_semi_ack(p, seqno, 0, sipmethod); 13224 } else { 13225 ack_res = __sip_ack(p, seqno, 0, sipmethod); 13226 } 13227 13228 if (ack_res == FALSE) { 13229 append_history(p, "Ignore", "Ignoring this retransmit\n"); 13230 return; 13231 } 13232 13233 /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */ 13234 if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 13235 p->pendinginvite = 0; 13236 13237 /* Get their tag if we haven't already */ 13238 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 13239 char tag[128]; 13240 13241 gettag(req, "To", tag, sizeof(tag)); 13242 ast_string_field_set(p, theirtag, tag); 13243 } 13244 13245 /* RFC 3261 Section 15 specifies that if we receive a 408 or 481 13246 * in response to a BYE, then we should end the current dialog 13247 * and session. It is known that at least one phone manufacturer 13248 * potentially will send a 404 in response to a BYE, so we'll be 13249 * liberal in what we accept and end the dialog and session if we 13250 * receive any of those responses to a BYE. 13251 */ 13252 if ((resp == 404 || resp == 408 || resp == 481) && sipmethod == SIP_BYE) { 13253 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13254 return; 13255 } 13256 13257 if (p->relatedpeer && p->method == SIP_OPTIONS) { 13258 /* We don't really care what the response is, just that it replied back. 13259 Well, as long as it's not a 100 response... since we might 13260 need to hang around for something more "definitive" */ 13261 if (resp != 100) 13262 handle_response_peerpoke(p, resp, req); 13263 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 13264 switch(resp) { 13265 case 100: /* 100 Trying */ 13266 case 101: /* 101 Dialog establishment */ 13267 if (sipmethod == SIP_INVITE) 13268 handle_response_invite(p, resp, rest, req, seqno); 13269 break; 13270 case 183: /* 183 Session Progress */ 13271 if (sipmethod == SIP_INVITE) 13272 handle_response_invite(p, resp, rest, req, seqno); 13273 break; 13274 case 180: /* 180 Ringing */ 13275 if (sipmethod == SIP_INVITE) 13276 handle_response_invite(p, resp, rest, req, seqno); 13277 break; 13278 case 182: /* 182 Queued */ 13279 if (sipmethod == SIP_INVITE) 13280 handle_response_invite(p, resp, rest, req, seqno); 13281 break; 13282 case 200: /* 200 OK */ 13283 p->authtries = 0; /* Reset authentication counter */ 13284 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 13285 /* We successfully transmitted a message 13286 or a video update request in INFO */ 13287 /* Nothing happens here - the message is inside a dialog */ 13288 } else if (sipmethod == SIP_INVITE) { 13289 handle_response_invite(p, resp, rest, req, seqno); 13290 } else if (sipmethod == SIP_NOTIFY) { 13291 /* They got the notify, this is the end */ 13292 if (p->owner) { 13293 if (!p->refer) { 13294 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 13295 ast_queue_hangup(p->owner); 13296 } else if (option_debug > 3) 13297 ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n"); 13298 } else { 13299 if (p->subscribed == NONE) 13300 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13301 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 13302 /* Ready to send the next state we have on queue */ 13303 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 13304 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 13305 } 13306 } 13307 } else if (sipmethod == SIP_REGISTER) 13308 res = handle_response_register(p, resp, rest, req, seqno); 13309 else if (sipmethod == SIP_BYE) { /* Ok, we're ready to go */ 13310 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13311 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 13312 } else if (sipmethod == SIP_SUBSCRIBE) 13313 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 13314 break; 13315 case 202: /* Transfer accepted */ 13316 if (sipmethod == SIP_REFER) 13317 handle_response_refer(p, resp, rest, req, seqno); 13318 break; 13319 case 401: /* Not www-authorized on SIP method */ 13320 if (sipmethod == SIP_INVITE) 13321 handle_response_invite(p, resp, rest, req, seqno); 13322 else if (sipmethod == SIP_REFER) 13323 handle_response_refer(p, resp, rest, req, seqno); 13324 else if (p->registry && sipmethod == SIP_REGISTER) 13325 res = handle_response_register(p, resp, rest, req, seqno); 13326 else if (sipmethod == SIP_BYE) { 13327 if (ast_strlen_zero(p->authname)) { 13328 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 13329 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 13330 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13331 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) { 13332 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13333 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13334 /* We fail to auth bye on our own call, but still needs to tear down the call. 13335 Life, they call it. */ 13336 } 13337 } else { 13338 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 13339 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13340 } 13341 break; 13342 case 403: /* Forbidden - we failed authentication */ 13343 if (sipmethod == SIP_INVITE) 13344 handle_response_invite(p, resp, rest, req, seqno); 13345 else if (p->registry && sipmethod == SIP_REGISTER) 13346 res = handle_response_register(p, resp, rest, req, seqno); 13347 else { 13348 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 13349 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13350 } 13351 break; 13352 case 404: /* Not found */ 13353 if (p->registry && sipmethod == SIP_REGISTER) 13354 res = handle_response_register(p, resp, rest, req, seqno); 13355 else if (sipmethod == SIP_INVITE) 13356 handle_response_invite(p, resp, rest, req, seqno); 13357 else if (owner) 13358 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13359 break; 13360 case 407: /* Proxy auth required */ 13361 if (sipmethod == SIP_INVITE) 13362 handle_response_invite(p, resp, rest, req, seqno); 13363 else if (sipmethod == SIP_REFER) 13364 handle_response_refer(p, resp, rest, req, seqno); 13365 else if (p->registry && sipmethod == SIP_REGISTER) 13366 res = handle_response_register(p, resp, rest, req, seqno); 13367 else if (sipmethod == SIP_BYE) { 13368 if (ast_strlen_zero(p->authname)) { 13369 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 13370 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 13371 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13372 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 13373 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13374 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13375 } 13376 } else /* We can't handle this, giving up in a bad way */ 13377 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13378 13379 break; 13380 case 408: /* Request timeout - terminate dialog */ 13381 if (sipmethod == SIP_INVITE) 13382 handle_response_invite(p, resp, rest, req, seqno); 13383 else if (sipmethod == SIP_REGISTER) 13384 res = handle_response_register(p, resp, rest, req, seqno); 13385 else if (sipmethod == SIP_BYE) { 13386 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13387 if (option_debug) 13388 ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 13389 } else { 13390 if (owner) 13391 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13392 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13393 } 13394 break; 13395 case 481: /* Call leg does not exist */ 13396 if (sipmethod == SIP_INVITE) { 13397 handle_response_invite(p, resp, rest, req, seqno); 13398 } else if (sipmethod == SIP_REFER) { 13399 handle_response_refer(p, resp, rest, req, seqno); 13400 } else if (sipmethod == SIP_BYE) { 13401 /* The other side has no transaction to bye, 13402 just assume it's all right then */ 13403 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13404 } else if (sipmethod == SIP_CANCEL) { 13405 /* The other side has no transaction to cancel, 13406 just assume it's all right then */ 13407 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13408 } else { 13409 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13410 /* Guessing that this is not an important request */ 13411 } 13412 break; 13413 case 487: 13414 if (sipmethod == SIP_INVITE) 13415 handle_response_invite(p, resp, rest, req, seqno); 13416 break; 13417 case 488: /* Not acceptable here - codec error */ 13418 if (sipmethod == SIP_INVITE) 13419 handle_response_invite(p, resp, rest, req, seqno); 13420 break; 13421 case 491: /* Pending */ 13422 if (sipmethod == SIP_INVITE) 13423 handle_response_invite(p, resp, rest, req, seqno); 13424 else { 13425 if (option_debug) 13426 ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 13427 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13428 } 13429 break; 13430 case 501: /* Not Implemented */ 13431 if (sipmethod == SIP_INVITE) 13432 handle_response_invite(p, resp, rest, req, seqno); 13433 else if (sipmethod == SIP_REFER) 13434 handle_response_refer(p, resp, rest, req, seqno); 13435 else 13436 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg); 13437 break; 13438 case 603: /* Declined transfer */ 13439 if (sipmethod == SIP_REFER) { 13440 handle_response_refer(p, resp, rest, req, seqno); 13441 break; 13442 } 13443 /* Fallthrough */ 13444 default: 13445 if ((resp >= 300) && (resp < 700)) { 13446 /* Fatal response */ 13447 if ((option_verbose > 2) && (resp != 487)) 13448 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 13449 13450 if (sipmethod == SIP_INVITE) 13451 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 13452 13453 /* XXX Locking issues?? XXX */ 13454 switch(resp) { 13455 case 300: /* Multiple Choices */ 13456 case 301: /* Moved permenantly */ 13457 case 302: /* Moved temporarily */ 13458 case 305: /* Use Proxy */ 13459 parse_moved_contact(p, req); 13460 /* Fall through */ 13461 case 486: /* Busy here */ 13462 case 600: /* Busy everywhere */ 13463 case 603: /* Decline */ 13464 if (p->owner) 13465 ast_queue_control(p->owner, AST_CONTROL_BUSY); 13466 break; 13467 case 482: /* 13468 \note SIP is incapable of performing a hairpin call, which 13469 is yet another failure of not having a layer 2 (again, YAY 13470 IETF for thinking ahead). So we treat this as a call 13471 forward and hope we end up at the right place... */ 13472 if (option_debug) 13473 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 13474 if (p->owner) 13475 ast_string_field_build(p->owner, call_forward, 13476 "Local/%s@%s", p->username, p->context); 13477 /* Fall through */ 13478 case 480: /* Temporarily Unavailable */ 13479 case 404: /* Not Found */ 13480 case 410: /* Gone */ 13481 case 400: /* Bad Request */ 13482 case 500: /* Server error */ 13483 if (sipmethod == SIP_REFER) { 13484 handle_response_refer(p, resp, rest, req, seqno); 13485 break; 13486 } 13487 /* Fall through */ 13488 case 502: /* Bad gateway */ 13489 case 503: /* Service Unavailable */ 13490 case 504: /* Server Timeout */ 13491 if (owner) 13492 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13493 break; 13494 default: 13495 /* Send hangup */ 13496 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE) 13497 ast_queue_hangup(p->owner); 13498 break; 13499 } 13500 /* ACK on invite */ 13501 if (sipmethod == SIP_INVITE) 13502 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13503 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 13504 sip_alreadygone(p); 13505 if (!p->owner) 13506 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13507 } else if ((resp >= 100) && (resp < 200)) { 13508 if (sipmethod == SIP_INVITE) { 13509 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13510 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13511 if (find_sdp(req)) 13512 process_sdp(p, req); 13513 if (p->owner) { 13514 /* Queue a progress frame */ 13515 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 13516 } 13517 } 13518 } else 13519 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)); 13520 } 13521 } else { 13522 /* Responses to OUTGOING SIP requests on INCOMING calls 13523 get handled here. As well as out-of-call message responses */ 13524 if (ast_test_flag(req, SIP_PKT_DEBUG)) 13525 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 13526 13527 if (sipmethod == SIP_INVITE && resp == 200) { 13528 /* Tags in early session is replaced by the tag in 200 OK, which is 13529 the final reply to our INVITE */ 13530 char tag[128]; 13531 13532 gettag(req, "To", tag, sizeof(tag)); 13533 ast_string_field_set(p, theirtag, tag); 13534 } 13535 13536 switch(resp) { 13537 case 200: 13538 if (sipmethod == SIP_INVITE) { 13539 handle_response_invite(p, resp, rest, req, seqno); 13540 } else if (sipmethod == SIP_CANCEL) { 13541 if (option_debug) 13542 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 13543 13544 /* Wait for 487, then destroy */ 13545 } else if (sipmethod == SIP_NOTIFY) { 13546 /* They got the notify, this is the end */ 13547 if (p->owner) { 13548 if (p->refer) { 13549 if (option_debug) 13550 ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n"); 13551 } else 13552 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 13553 /* ast_queue_hangup(p->owner); Disabled */ 13554 } else { 13555 if (!p->subscribed && !p->refer) 13556 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13557 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 13558 /* Ready to send the next state we have on queue */ 13559 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 13560 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 13561 } 13562 } 13563 } else if (sipmethod == SIP_BYE) 13564 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13565 else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) 13566 /* We successfully transmitted a message or 13567 a video update request in INFO */ 13568 ; 13569 else if (sipmethod == SIP_BYE) 13570 /* Ok, we're ready to go */ 13571 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13572 break; 13573 case 202: /* Transfer accepted */ 13574 if (sipmethod == SIP_REFER) 13575 handle_response_refer(p, resp, rest, req, seqno); 13576 break; 13577 case 401: /* www-auth */ 13578 case 407: 13579 if (sipmethod == SIP_REFER) 13580 handle_response_refer(p, resp, rest, req, seqno); 13581 else if (sipmethod == SIP_INVITE) 13582 handle_response_invite(p, resp, rest, req, seqno); 13583 else if (sipmethod == SIP_BYE) { 13584 char *auth, *auth2; 13585 13586 auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate"); 13587 auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization"); 13588 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 13589 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13590 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13591 } 13592 } 13593 break; 13594 case 481: /* Call leg does not exist */ 13595 if (sipmethod == SIP_INVITE) { 13596 /* Re-invite failed */ 13597 handle_response_invite(p, resp, rest, req, seqno); 13598 } else if (sipmethod == SIP_BYE) { 13599 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13600 } else if (sipdebug) { 13601 ast_log (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 13602 } 13603 break; 13604 case 501: /* Not Implemented */ 13605 if (sipmethod == SIP_INVITE) 13606 handle_response_invite(p, resp, rest, req, seqno); 13607 else if (sipmethod == SIP_REFER) 13608 handle_response_refer(p, resp, rest, req, seqno); 13609 break; 13610 case 603: /* Declined transfer */ 13611 if (sipmethod == SIP_REFER) { 13612 handle_response_refer(p, resp, rest, req, seqno); 13613 break; 13614 } 13615 /* Fallthrough */ 13616 default: /* Errors without handlers */ 13617 if ((resp >= 100) && (resp < 200)) { 13618 if (sipmethod == SIP_INVITE) { /* re-invite */ 13619 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13620 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13621 } 13622 } 13623 if ((resp >= 300) && (resp < 700)) { 13624 if ((option_verbose > 2) && (resp != 487)) 13625 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)); 13626 switch(resp) { 13627 case 488: /* Not acceptable here - codec error */ 13628 case 603: /* Decline */ 13629 case 500: /* Server error */ 13630 case 502: /* Bad gateway */ 13631 case 503: /* Service Unavailable */ 13632 case 504: /* Server timeout */ 13633 13634 /* re-invite failed */ 13635 if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) 13636 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13637 break; 13638 } 13639 } 13640 break; 13641 } 13642 } 13643 }
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 12618 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_PAGE2_OUTGOING_CALL, 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_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().
12619 { 12620 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 12621 int res = 0; 12622 int xmitres = 0; 12623 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 12624 struct ast_channel *bridgepeer = NULL; 12625 12626 if (option_debug > 3) { 12627 if (reinvite) 12628 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 12629 else 12630 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 12631 } 12632 12633 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */ 12634 if (option_debug) 12635 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 12636 return; 12637 } 12638 12639 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 12640 /* Don't auto congest anymore since we've gotten something useful back */ 12641 AST_SCHED_DEL(sched, p->initid); 12642 12643 /* RFC3261 says we must treat every 1xx response (but not 100) 12644 that we don't recognize as if it was 183. 12645 */ 12646 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183) 12647 resp = 183; 12648 12649 /* Any response between 100 and 199 is PROCEEDING */ 12650 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 12651 p->invitestate = INV_PROCEEDING; 12652 12653 /* Final response, not 200 ? */ 12654 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 12655 p->invitestate = INV_COMPLETED; 12656 12657 12658 switch (resp) { 12659 case 100: /* Trying */ 12660 case 101: /* Dialog establishment */ 12661 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12662 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12663 check_pendings(p); 12664 break; 12665 12666 case 180: /* 180 Ringing */ 12667 case 182: /* 182 Queued */ 12668 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12669 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12670 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12671 ast_queue_control(p->owner, AST_CONTROL_RINGING); 12672 if (p->owner->_state != AST_STATE_UP) { 12673 ast_setstate(p->owner, AST_STATE_RINGING); 12674 } 12675 } 12676 if (find_sdp(req)) { 12677 if (p->invitestate != INV_CANCELLED) 12678 p->invitestate = INV_EARLY_MEDIA; 12679 res = process_sdp(p, req); 12680 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12681 /* Queue a progress frame only if we have SDP in 180 or 182 */ 12682 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12683 } 12684 } 12685 check_pendings(p); 12686 break; 12687 12688 case 183: /* Session progress */ 12689 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12690 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12691 /* Ignore 183 Session progress without SDP */ 12692 if (find_sdp(req)) { 12693 if (p->invitestate != INV_CANCELLED) 12694 p->invitestate = INV_EARLY_MEDIA; 12695 res = process_sdp(p, req); 12696 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12697 /* Queue a progress frame */ 12698 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12699 } 12700 } 12701 check_pendings(p); 12702 break; 12703 12704 case 200: /* 200 OK on invite - someone's answering our call */ 12705 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12706 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12707 p->authtries = 0; 12708 if (find_sdp(req)) { 12709 if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) 12710 if (!reinvite) 12711 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 12712 /* For re-invites, we try to recover */ 12713 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12714 } 12715 12716 /* Parse contact header for continued conversation */ 12717 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 12718 /* This is important when we have a SIP proxy between us and the phone */ 12719 if (outgoing) { 12720 update_call_counter(p, DEC_CALL_RINGING); 12721 parse_ok_contact(p, req); 12722 /* Save Record-Route for any later requests we make on this dialogue */ 12723 if (!reinvite) 12724 build_route(p, req, 1); 12725 12726 if(set_address_from_contact(p)) { 12727 /* Bad contact - we don't know how to reach this device */ 12728 /* We need to ACK, but then send a bye */ 12729 if (!p->route && !ast_test_flag(req, SIP_PKT_IGNORE)) 12730 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12731 } 12732 12733 } 12734 12735 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 12736 struct sip_pvt *bridgepvt = NULL; 12737 12738 if (!bridgepeer->tech) { 12739 ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n"); 12740 break; 12741 } 12742 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 12743 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 12744 if (bridgepvt->udptl) { 12745 if (p->t38.state == T38_PEER_REINVITE) { 12746 sip_handle_t38_reinvite(bridgepeer, p, 0); 12747 ast_rtp_set_rtptimers_onhold(p->rtp); 12748 if (p->vrtp) 12749 ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */ 12750 } 12751 } else { 12752 if (option_debug > 1) 12753 ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n"); 12754 ast_mutex_lock(&bridgepvt->lock); 12755 bridgepvt->t38.state = T38_DISABLED; 12756 ast_mutex_unlock(&bridgepvt->lock); 12757 if (option_debug) 12758 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type); 12759 p->t38.state = T38_DISABLED; 12760 if (option_debug > 1) 12761 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12762 } 12763 } else { 12764 /* Other side is not a SIP channel */ 12765 if (option_debug > 1) 12766 ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n"); 12767 p->t38.state = T38_DISABLED; 12768 if (option_debug > 1) 12769 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12770 } 12771 } 12772 if (p->t38.state == T38_LOCAL_REINVITE) { 12773 /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */ 12774 p->t38.state = T38_ENABLED; 12775 if (option_debug) 12776 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12777 } 12778 12779 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12780 if (!reinvite) { 12781 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 12782 } else { /* RE-invite */ 12783 ast_queue_frame(p->owner, &ast_null_frame); 12784 } 12785 } else { 12786 /* It's possible we're getting an 200 OK after we've tried to disconnect 12787 by sending CANCEL */ 12788 /* First send ACK, then send bye */ 12789 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12790 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12791 } 12792 /* If I understand this right, the branch is different for a non-200 ACK only */ 12793 p->invitestate = INV_TERMINATED; 12794 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 12795 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 12796 check_pendings(p); 12797 break; 12798 case 407: /* Proxy authentication */ 12799 case 401: /* Www auth */ 12800 /* First we ACK */ 12801 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12802 if (p->options) 12803 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 12804 12805 /* Then we AUTH */ 12806 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 12807 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12808 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 12809 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 12810 if (p->authtries < MAX_AUTHTRIES) 12811 p->invitestate = INV_CALLING; 12812 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 12813 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 12814 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12815 sip_alreadygone(p); 12816 if (p->owner) 12817 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12818 } 12819 } 12820 break; 12821 12822 case 403: /* Forbidden */ 12823 /* First we ACK */ 12824 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12825 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 12826 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) 12827 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12828 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12829 sip_alreadygone(p); 12830 break; 12831 12832 case 404: /* Not found */ 12833 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12834 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12835 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12836 sip_alreadygone(p); 12837 break; 12838 12839 case 408: /* Request timeout */ 12840 case 481: /* Call leg does not exist */ 12841 /* Could be REFER caused INVITE with replaces */ 12842 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 12843 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12844 if (p->owner) 12845 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12846 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12847 break; 12848 case 487: /* Cancelled transaction */ 12849 /* We have sent CANCEL on an outbound INVITE 12850 This transaction is already scheduled to be killed by sip_hangup(). 12851 */ 12852 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12853 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12854 ast_queue_hangup(p->owner); 12855 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 12856 } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12857 update_call_counter(p, DEC_CALL_LIMIT); 12858 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 12859 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12860 sip_alreadygone(p); 12861 } 12862 break; 12863 case 488: /* Not acceptable here */ 12864 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12865 if (reinvite && p->udptl) { 12866 /* If this is a T.38 call, we should go back to 12867 audio. If this is an audio call - something went 12868 terribly wrong since we don't renegotiate codecs, 12869 only IP/port . 12870 */ 12871 p->t38.state = T38_DISABLED; 12872 /* Try to reset RTP timers */ 12873 ast_rtp_set_rtptimers_onhold(p->rtp); 12874 ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n"); 12875 12876 /*! \bug Is there any way we can go back to the audio call on both 12877 sides here? 12878 */ 12879 /* While figuring that out, hangup the call */ 12880 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12881 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12882 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12883 } else { 12884 /* We can't set up this call, so give up */ 12885 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12886 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12887 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12888 /* If there's no dialog to end, then mark p as already gone */ 12889 if (!reinvite) 12890 sip_alreadygone(p); 12891 } 12892 break; 12893 case 491: /* Pending */ 12894 /* we really should have to wait a while, then retransmit 12895 * We should support the retry-after at some point 12896 * At this point, we treat this as a congestion if the call is not in UP state 12897 */ 12898 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12899 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12900 if (p->owner->_state != AST_STATE_UP) { 12901 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12902 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12903 } else { 12904 /* This is a re-invite that failed. 12905 * Reset the flag after a while 12906 */ 12907 int wait; 12908 /* RFC 3261, if owner of call, wait between 2.1 to 4 seconds, 12909 * if not owner of call, wait 0 to 2 seconds */ 12910 if (ast_test_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL)) { 12911 wait = 2100 + ast_random() % 2000; 12912 } else { 12913 wait = ast_random() % 2000; 12914 } 12915 p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p); 12916 if (option_debug > 2) 12917 ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait); 12918 } 12919 } 12920 break; 12921 12922 case 501: /* Not implemented */ 12923 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12924 if (p->owner) 12925 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12926 break; 12927 } 12928 if (xmitres == XMIT_ERROR) 12929 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 12930 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 13128 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), ast_update_realtime(), ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::call, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, EVENT_FLAG_SYSTEM, sip_pvt::flags, global_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, SIP_PAGE2_RTUPDATE, and sip_poke_peer_s().
Referenced by handle_response().
13129 { 13130 struct sip_peer *peer = p->relatedpeer; 13131 int statechanged, is_reachable, was_reachable; 13132 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 13133 13134 /* 13135 * Compute the response time to a ping (goes in peer->lastms.) 13136 * -1 means did not respond, 0 means unknown, 13137 * 1..maxms is a valid response, >maxms means late response. 13138 */ 13139 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 13140 pingtime = 1; 13141 13142 /* Now determine new state and whether it has changed. 13143 * Use some helper variables to simplify the writing 13144 * of the expressions. 13145 */ 13146 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 13147 is_reachable = pingtime <= peer->maxms; 13148 statechanged = peer->lastms == 0 /* yes, unknown before */ 13149 || was_reachable != is_reachable; 13150 13151 peer->lastms = pingtime; 13152 peer->call = NULL; 13153 if (statechanged) { 13154 const char *s = is_reachable ? "Reachable" : "Lagged"; 13155 char str_lastms[20]; 13156 snprintf(str_lastms, sizeof(str_lastms), "%d", pingtime); 13157 13158 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 13159 peer->name, s, pingtime, peer->maxms); 13160 ast_device_state_changed("SIP/%s", peer->name); 13161 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE)) { 13162 ast_update_realtime("sippeers", "name", peer->name, "lastms", str_lastms, NULL); 13163 } 13164 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 13165 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 13166 peer->name, s, pingtime); 13167 } 13168 13169 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 13170 struct sip_peer *peer_ptr = peer; 13171 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 13172 } 13173 13174 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13175 13176 /* Try again eventually */ 13177 peer->pokeexpire = ast_sched_add(sched, 13178 is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, 13179 sip_poke_peer_s, ASTOBJ_REF(peer)); 13180 13181 if (peer->pokeexpire == -1) { 13182 ASTOBJ_UNREF(peer, sip_destroy_peer); 13183 } 13184 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 12935 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().
12936 { 12937 char *auth = "Proxy-Authenticate"; 12938 char *auth2 = "Proxy-Authorization"; 12939 12940 /* If no refer structure exists, then do nothing */ 12941 if (!p->refer) 12942 return; 12943 12944 switch (resp) { 12945 case 202: /* Transfer accepted */ 12946 /* We need to do something here */ 12947 /* The transferee is now sending INVITE to target */ 12948 p->refer->status = REFER_ACCEPTED; 12949 /* Now wait for next message */ 12950 if (option_debug > 2) 12951 ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n"); 12952 /* We should hang along, waiting for NOTIFY's here */ 12953 break; 12954 12955 case 401: /* Not www-authorized on SIP method */ 12956 case 407: /* Proxy auth */ 12957 if (ast_strlen_zero(p->authname)) { 12958 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 12959 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12960 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12961 } 12962 if (resp == 401) { 12963 auth = "WWW-Authenticate"; 12964 auth2 = "Authorization"; 12965 } 12966 if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) { 12967 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 12968 p->refer->status = REFER_NOAUTH; 12969 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12970 } 12971 break; 12972 case 481: /* Call leg does not exist */ 12973 12974 /* A transfer with Replaces did not work */ 12975 /* OEJ: We should Set flag, cancel the REFER, go back 12976 to original call - but right now we can't */ 12977 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 12978 if (p->owner) 12979 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12980 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12981 break; 12982 12983 case 500: /* Server error */ 12984 case 501: /* Method not implemented */ 12985 /* Return to the current call onhold */ 12986 /* Status flag needed to be reset */ 12987 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 12988 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12989 p->refer->status = REFER_FAILED; 12990 break; 12991 case 603: /* Transfer declined */ 12992 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 12993 p->refer->status = REFER_FAILED; 12994 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12995 break; 12996 } 12997 }
static int handle_response_register | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Handle responses on REGISTER to services.
Definition at line 13000 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_pvt::callid, 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().
13001 { 13002 int expires, expires_ms; 13003 struct sip_registry *r; 13004 r=p->registry; 13005 13006 switch (resp) { 13007 case 401: /* Unauthorized */ 13008 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 13009 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 13010 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13011 } 13012 break; 13013 case 403: /* Forbidden */ 13014 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 13015 if (global_regattempts_max) 13016 p->registry->regattempts = global_regattempts_max+1; 13017 AST_SCHED_DEL(sched, r->timeout); 13018 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13019 break; 13020 case 404: /* Not found */ 13021 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 13022 if (global_regattempts_max) 13023 p->registry->regattempts = global_regattempts_max+1; 13024 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13025 r->call = NULL; 13026 AST_SCHED_DEL(sched, r->timeout); 13027 break; 13028 case 407: /* Proxy auth */ 13029 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 13030 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 13031 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13032 } 13033 break; 13034 case 408: /* Request timeout */ 13035 /* Got a timeout response, so reset the counter of failed responses */ 13036 if (r) { 13037 r->regattempts = 0; 13038 } else { 13039 ast_log(LOG_WARNING, "Got a 408 response to our REGISTER on call %s after we had destroyed the registry object\n", p->callid); 13040 } 13041 break; 13042 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 13043 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 13044 if (global_regattempts_max) 13045 p->registry->regattempts = global_regattempts_max+1; 13046 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13047 r->call = NULL; 13048 AST_SCHED_DEL(sched, r->timeout); 13049 break; 13050 case 200: /* 200 OK */ 13051 if (!r) { 13052 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)); 13053 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13054 return 0; 13055 } 13056 13057 r->regstate = REG_STATE_REGISTERED; 13058 r->regtime = time(NULL); /* Reset time of last succesful registration */ 13059 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 13060 r->regattempts = 0; 13061 if (option_debug) 13062 ast_log(LOG_DEBUG, "Registration successful\n"); 13063 if (r->timeout > -1) { 13064 if (option_debug) 13065 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 13066 } 13067 AST_SCHED_DEL(sched, r->timeout); 13068 r->call = NULL; 13069 p->registry = NULL; 13070 /* Let this one hang around until we have all the responses */ 13071 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13072 /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */ 13073 13074 /* set us up for re-registering */ 13075 /* figure out how long we got registered for */ 13076 AST_SCHED_DEL(sched, r->expire); 13077 /* according to section 6.13 of RFC, contact headers override 13078 expires headers, so check those first */ 13079 expires = 0; 13080 13081 /* XXX todo: try to save the extra call */ 13082 if (!ast_strlen_zero(get_header(req, "Contact"))) { 13083 const char *contact = NULL; 13084 const char *tmptmp = NULL; 13085 int start = 0; 13086 for(;;) { 13087 contact = __get_header(req, "Contact", &start); 13088 /* this loop ensures we get a contact header about our register request */ 13089 if(!ast_strlen_zero(contact)) { 13090 if( (tmptmp=strstr(contact, p->our_contact))) { 13091 contact=tmptmp; 13092 break; 13093 } 13094 } else 13095 break; 13096 } 13097 tmptmp = strcasestr(contact, "expires="); 13098 if (tmptmp) { 13099 if (sscanf(tmptmp + 8, "%30d;", &expires) != 1) 13100 expires = 0; 13101 } 13102 13103 } 13104 if (!expires) 13105 expires=atoi(get_header(req, "expires")); 13106 if (!expires) 13107 expires=default_expiry; 13108 13109 expires_ms = expires * 1000; 13110 if (expires <= EXPIRY_GUARD_LIMIT) 13111 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 13112 else 13113 expires_ms -= EXPIRY_GUARD_SECS * 1000; 13114 if (sipdebug) 13115 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 13116 13117 r->refresh= (int) expires_ms / 1000; 13118 13119 /* Schedule re-registration before we expire */ 13120 AST_SCHED_DEL(sched, r->expire); 13121 r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 13122 ASTOBJ_UNREF(r, sip_registry_destroy); 13123 } 13124 return 1; 13125 }
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 3527 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().
03528 { 03529 switch (cause) { 03530 case AST_CAUSE_UNALLOCATED: /* 1 */ 03531 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 03532 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 03533 return "404 Not Found"; 03534 case AST_CAUSE_CONGESTION: /* 34 */ 03535 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 03536 return "503 Service Unavailable"; 03537 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 03538 return "408 Request Timeout"; 03539 case AST_CAUSE_NO_ANSWER: /* 19 */ 03540 case AST_CAUSE_UNREGISTERED: /* 20 */ 03541 return "480 Temporarily unavailable"; 03542 case AST_CAUSE_CALL_REJECTED: /* 21 */ 03543 return "403 Forbidden"; 03544 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 03545 return "410 Gone"; 03546 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 03547 return "480 Temporarily unavailable"; 03548 case AST_CAUSE_INVALID_NUMBER_FORMAT: 03549 return "484 Address incomplete"; 03550 case AST_CAUSE_USER_BUSY: 03551 return "486 Busy here"; 03552 case AST_CAUSE_FAILURE: 03553 return "500 Server internal failure"; 03554 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 03555 return "501 Not Implemented"; 03556 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 03557 return "503 Service Unavailable"; 03558 /* Used in chan_iax2 */ 03559 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 03560 return "502 Bad Gateway"; 03561 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 03562 return "488 Not Acceptable Here"; 03563 03564 case AST_CAUSE_NOTDEFINED: 03565 default: 03566 if (option_debug) 03567 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 03568 return NULL; 03569 } 03570 03571 /* Never reached */ 03572 return 0; 03573 }
static int hangup_sip2cause | ( | int | cause | ) | [static] |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 3415 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_NUMBER_CHANGED, AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, AST_CAUSE_UNALLOCATED, and AST_CAUSE_USER_BUSY.
Referenced by handle_response().
03416 { 03417 /* Possible values taken from causes.h */ 03418 03419 switch(cause) { 03420 case 401: /* Unauthorized */ 03421 return AST_CAUSE_CALL_REJECTED; 03422 case 403: /* Not found */ 03423 return AST_CAUSE_CALL_REJECTED; 03424 case 404: /* Not found */ 03425 return AST_CAUSE_UNALLOCATED; 03426 case 405: /* Method not allowed */ 03427 return AST_CAUSE_INTERWORKING; 03428 case 407: /* Proxy authentication required */ 03429 return AST_CAUSE_CALL_REJECTED; 03430 case 408: /* No reaction */ 03431 return AST_CAUSE_NO_USER_RESPONSE; 03432 case 409: /* Conflict */ 03433 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 03434 case 410: /* Gone */ 03435 return AST_CAUSE_NUMBER_CHANGED; 03436 case 411: /* Length required */ 03437 return AST_CAUSE_INTERWORKING; 03438 case 413: /* Request entity too large */ 03439 return AST_CAUSE_INTERWORKING; 03440 case 414: /* Request URI too large */ 03441 return AST_CAUSE_INTERWORKING; 03442 case 415: /* Unsupported media type */ 03443 return AST_CAUSE_INTERWORKING; 03444 case 420: /* Bad extension */ 03445 return AST_CAUSE_NO_ROUTE_DESTINATION; 03446 case 480: /* No answer */ 03447 return AST_CAUSE_NO_ANSWER; 03448 case 481: /* No answer */ 03449 return AST_CAUSE_INTERWORKING; 03450 case 482: /* Loop detected */ 03451 return AST_CAUSE_INTERWORKING; 03452 case 483: /* Too many hops */ 03453 return AST_CAUSE_NO_ANSWER; 03454 case 484: /* Address incomplete */ 03455 return AST_CAUSE_INVALID_NUMBER_FORMAT; 03456 case 485: /* Ambigous */ 03457 return AST_CAUSE_UNALLOCATED; 03458 case 486: /* Busy everywhere */ 03459 return AST_CAUSE_BUSY; 03460 case 487: /* Request terminated */ 03461 return AST_CAUSE_INTERWORKING; 03462 case 488: /* No codecs approved */ 03463 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03464 case 491: /* Request pending */ 03465 return AST_CAUSE_INTERWORKING; 03466 case 493: /* Undecipherable */ 03467 return AST_CAUSE_INTERWORKING; 03468 case 500: /* Server internal failure */ 03469 return AST_CAUSE_FAILURE; 03470 case 501: /* Call rejected */ 03471 return AST_CAUSE_FACILITY_REJECTED; 03472 case 502: 03473 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03474 case 503: /* Service unavailable */ 03475 return AST_CAUSE_CONGESTION; 03476 case 504: /* Gateway timeout */ 03477 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 03478 case 505: /* SIP version not supported */ 03479 return AST_CAUSE_INTERWORKING; 03480 case 600: /* Busy everywhere */ 03481 return AST_CAUSE_USER_BUSY; 03482 case 603: /* Decline */ 03483 return AST_CAUSE_CALL_REJECTED; 03484 case 604: /* Does not exist anywhere */ 03485 return AST_CAUSE_UNALLOCATED; 03486 case 606: /* Not acceptable */ 03487 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03488 default: 03489 return AST_CAUSE_NORMAL; 03490 } 03491 /* Never reached */ 03492 return 0; 03493 }
static int init_req | ( | struct sip_request * | req, | |
int | sipmethod, | |||
const char * | recip | |||
) | [static] |
Initialize SIP request.
Definition at line 6132 of file chan_sip.c.
References sip_methods, and cfsip_methods::text.
06133 { 06134 /* Initialize a request */ 06135 memset(req, 0, sizeof(*req)); 06136 req->method = sipmethod; 06137 req->header[0] = req->data; 06138 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 06139 req->len = strlen(req->header[0]); 06140 req->headers++; 06141 return 0; 06142 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 6119 of file chan_sip.c.
References SIP_RESPONSE.
06120 { 06121 /* Initialize a response */ 06122 memset(resp, 0, sizeof(*resp)); 06123 resp->method = SIP_RESPONSE; 06124 resp->header[0] = resp->data; 06125 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 06126 resp->len = strlen(resp->header[0]); 06127 resp->headers++; 06128 return 0; 06129 }
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 1666 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().
01667 { 01668 if (p->initreq.headers && option_debug) { 01669 ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 01670 } 01671 /* Use this as the basis */ 01672 copy_request(&p->initreq, req); 01673 parse_request(&p->initreq); 01674 if (ast_test_flag(req, SIP_PKT_DEBUG)) 01675 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 01676 }
static void initreqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod | |||
) | [static] |
Initiate new SIP request to peer/user.
Definition at line 7249 of file chan_sip.c.
References add_header(), add_route(), 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::route, 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().
07250 { 07251 char invite_buf[256] = ""; 07252 char *invite = invite_buf; 07253 size_t invite_max = sizeof(invite_buf); 07254 char from[256]; 07255 char to[256]; 07256 char tmp[SIPBUFSIZE/2]; 07257 char tmp2[SIPBUFSIZE/2]; 07258 const char *l = NULL, *n = NULL; 07259 const char *urioptions = ""; 07260 07261 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 07262 const char *s = p->username; /* being a string field, cannot be NULL */ 07263 07264 /* Test p->username against allowed characters in AST_DIGIT_ANY 07265 If it matches the allowed characters list, then sipuser = ";user=phone" 07266 If not, then sipuser = "" 07267 */ 07268 /* + is allowed in first position in a tel: uri */ 07269 if (*s == '+') 07270 s++; 07271 for (; *s; s++) { 07272 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 07273 break; 07274 } 07275 /* If we have only digits, add ;user=phone to the uri */ 07276 if (!*s) 07277 urioptions = ";user=phone"; 07278 } 07279 07280 07281 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 07282 07283 if (p->owner) { 07284 l = p->owner->cid.cid_num; 07285 n = p->owner->cid.cid_name; 07286 } 07287 /* if we are not sending RPID and user wants his callerid restricted */ 07288 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 07289 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 07290 l = CALLERID_UNKNOWN; 07291 n = l; 07292 } 07293 if (ast_strlen_zero(l)) 07294 l = default_callerid; 07295 if (ast_strlen_zero(n)) 07296 n = l; 07297 /* Allow user to be overridden */ 07298 if (!ast_strlen_zero(p->fromuser)) 07299 l = p->fromuser; 07300 else /* Save for any further attempts */ 07301 ast_string_field_set(p, fromuser, l); 07302 07303 /* Allow user to be overridden */ 07304 if (!ast_strlen_zero(p->fromname)) 07305 n = p->fromname; 07306 else /* Save for any further attempts */ 07307 ast_string_field_set(p, fromname, n); 07308 07309 if (pedanticsipchecking) { 07310 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07311 n = tmp; 07312 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 07313 l = tmp2; 07314 } 07315 07316 if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain)) 07317 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); 07318 else 07319 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag); 07320 07321 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 07322 if (!ast_strlen_zero(p->fullcontact)) { 07323 /* If we have full contact, trust it */ 07324 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 07325 } else { 07326 /* Otherwise, use the username while waiting for registration */ 07327 ast_build_string(&invite, &invite_max, "sip:"); 07328 if (!ast_strlen_zero(p->username)) { 07329 n = p->username; 07330 if (pedanticsipchecking) { 07331 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07332 n = tmp; 07333 } 07334 ast_build_string(&invite, &invite_max, "%s@", n); 07335 } 07336 ast_build_string(&invite, &invite_max, "%s", p->tohost); 07337 if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT) 07338 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 07339 ast_build_string(&invite, &invite_max, "%s", urioptions); 07340 } 07341 07342 /* If custom URI options have been provided, append them */ 07343 if (p->options && !ast_strlen_zero(p->options->uri_options)) 07344 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 07345 07346 ast_string_field_set(p, uri, invite_buf); 07347 07348 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 07349 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 07350 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (!strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag); 07351 } else if (p->options && p->options->vxml_url) { 07352 /* If there is a VXML URL append it to the SIP URL */ 07353 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 07354 } else 07355 snprintf(to, sizeof(to), "<%s>", p->uri); 07356 07357 init_req(req, sipmethod, p->uri); 07358 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 07359 07360 add_header(req, "Via", p->via); 07361 /* This will be a no-op most of the time. However, under certain circumstances, 07362 * NOTIFY messages will use this function for preparing the request and should 07363 * have Route headers present. 07364 */ 07365 add_route(req, p->route); 07366 /* Build Remote Party-ID and From */ 07367 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 07368 build_rpid(p); 07369 add_header(req, "From", p->rpid_from); 07370 } else 07371 add_header(req, "From", from); 07372 add_header(req, "To", to); 07373 ast_string_field_set(p, exten, l); 07374 build_contact(p); 07375 add_header(req, "Contact", p->our_contact); 07376 add_header(req, "Call-ID", p->callid); 07377 add_header(req, "CSeq", tmp); 07378 if (!ast_strlen_zero(global_useragent)) 07379 add_header(req, "User-Agent", global_useragent); 07380 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07381 if (!ast_strlen_zero(p->rpid)) 07382 add_header(req, "Remote-Party-ID", p->rpid); 07383 }
static const char * insecure2str | ( | int | port, | |
int | invite | |||
) | const [static] |
Convert Insecure setting to printable string.
Definition at line 10610 of file chan_sip.c.
Referenced by _sip_show_peer().
10611 { 10612 if (port && invite) 10613 return "port,invite"; 10614 else if (port) 10615 return "port"; 10616 else if (invite) 10617 return "invite"; 10618 else 10619 return "no"; 10620 }
static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 8624 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
08625 { 08626 if (!route) 08627 ast_verbose("list_route: no route\n"); 08628 else { 08629 for (;route; route = route->next) 08630 ast_verbose("list_route: hop: <%s>\n", route->hop); 08631 } 08632 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 19195 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.
19196 { 19197 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 19198 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 19199 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 19200 19201 if (!(sched = sched_context_create())) { 19202 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 19203 return AST_MODULE_LOAD_FAILURE; 19204 } 19205 19206 if (!(io = io_context_create())) { 19207 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 19208 sched_context_destroy(sched); 19209 return AST_MODULE_LOAD_FAILURE; 19210 } 19211 19212 sip_reloadreason = CHANNEL_MODULE_LOAD; 19213 19214 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 19215 return AST_MODULE_LOAD_DECLINE; 19216 19217 /* Make sure we can register our sip channel type */ 19218 if (ast_channel_register(&sip_tech)) { 19219 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 19220 io_context_destroy(io); 19221 sched_context_destroy(sched); 19222 return AST_MODULE_LOAD_FAILURE; 19223 } 19224 19225 /* Register all CLI functions for SIP */ 19226 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 19227 19228 /* Tell the RTP subdriver that we're here */ 19229 ast_rtp_proto_register(&sip_rtp); 19230 19231 /* Tell the UDPTL subdriver that we're here */ 19232 ast_udptl_proto_register(&sip_udptl); 19233 19234 /* Register dialplan applications */ 19235 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 19236 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 19237 19238 /* Register dialplan functions */ 19239 ast_custom_function_register(&sip_header_function); 19240 ast_custom_function_register(&sippeer_function); 19241 ast_custom_function_register(&sipchaninfo_function); 19242 ast_custom_function_register(&checksipdomain_function); 19243 19244 /* Register manager commands */ 19245 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 19246 "List SIP peers (text format)", mandescr_show_peers); 19247 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 19248 "Show SIP peer (text format)", mandescr_show_peer); 19249 19250 sip_poke_all_peers(); 19251 sip_send_all_registers(); 19252 19253 /* And start the monitor for the first time */ 19254 restart_monitor(); 19255 19256 return AST_MODULE_LOAD_SUCCESS; 19257 }
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 15137 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().
15138 { 15139 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 15140 /* Chan 2: Call from Asterisk to target */ 15141 int res = 0; 15142 struct sip_pvt *targetcall_pvt; 15143 15144 /* Check if the call ID of the replaces header does exist locally */ 15145 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 15146 transferer->refer->replaces_callid_fromtag))) { 15147 if (transferer->refer->localtransfer) { 15148 /* We did not find the refered call. Sorry, can't accept then */ 15149 transmit_response(transferer, "202 Accepted", req); 15150 /* Let's fake a response from someone else in order 15151 to follow the standard */ 15152 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 15153 append_history(transferer, "Xfer", "Refer failed"); 15154 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 15155 transferer->refer->status = REFER_FAILED; 15156 return -1; 15157 } 15158 /* Fall through for remote transfers that we did not find locally */ 15159 if (option_debug > 2) 15160 ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 15161 return 0; 15162 } 15163 15164 /* Ok, we can accept this transfer */ 15165 transmit_response(transferer, "202 Accepted", req); 15166 append_history(transferer, "Xfer", "Refer accepted"); 15167 if (!targetcall_pvt->owner) { /* No active channel */ 15168 if (option_debug > 3) 15169 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n"); 15170 /* Cancel transfer */ 15171 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 15172 append_history(transferer, "Xfer", "Refer failed"); 15173 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 15174 transferer->refer->status = REFER_FAILED; 15175 ast_mutex_unlock(&targetcall_pvt->lock); 15176 return -1; 15177 } 15178 15179 /* We have a channel, find the bridge */ 15180 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 15181 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 15182 15183 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 15184 /* Wrong state of new channel */ 15185 if (option_debug > 3) { 15186 if (target.chan2) 15187 ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 15188 else if (target.chan1->_state != AST_STATE_RING) 15189 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n"); 15190 else 15191 ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n"); 15192 } 15193 } 15194 15195 /* Transfer */ 15196 if (option_debug > 3 && sipdebug) { 15197 if (current->chan2) /* We have two bridges */ 15198 ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 15199 else /* One bridge, propably transfer of IVR/voicemail etc */ 15200 ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 15201 } 15202 15203 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 15204 15205 /* Perform the transfer */ 15206 res = attempt_transfer(current, &target); 15207 ast_mutex_unlock(&targetcall_pvt->lock); 15208 if (res) { 15209 /* Failed transfer */ 15210 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 15211 append_history(transferer, "Xfer", "Refer failed"); 15212 transferer->refer->status = REFER_FAILED; 15213 if (targetcall_pvt->owner) 15214 ast_channel_unlock(targetcall_pvt->owner); 15215 /* Right now, we have to hangup, sorry. Bridge is destroyed */ 15216 if (res != -2) 15217 ast_hangup(transferer->owner); 15218 else 15219 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 15220 } else { 15221 /* Transfer succeeded! */ 15222 15223 /* Tell transferer that we're done. */ 15224 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 15225 append_history(transferer, "Xfer", "Refer succeeded"); 15226 transferer->refer->status = REFER_200OK; 15227 if (targetcall_pvt->owner) { 15228 if (option_debug) 15229 ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 15230 ast_channel_unlock(targetcall_pvt->owner); 15231 } 15232 } 15233 return 1; 15234 }
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 4930 of file chan_sip.c.
References t.
Referenced by sipsock_read().
04931 { 04932 int h = 0, t = 0; 04933 int lws = 0; 04934 04935 for (; h < len;) { 04936 /* Eliminate all CRs */ 04937 if (msgbuf[h] == '\r') { 04938 h++; 04939 continue; 04940 } 04941 /* Check for end-of-line */ 04942 if (msgbuf[h] == '\n') { 04943 /* Check for end-of-message */ 04944 if (h + 1 == len) 04945 break; 04946 /* Check for a continuation line */ 04947 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 04948 /* Merge continuation line */ 04949 h++; 04950 continue; 04951 } 04952 /* Propagate LF and start new line */ 04953 msgbuf[t++] = msgbuf[h++]; 04954 lws = 0; 04955 continue; 04956 } 04957 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 04958 if (lws) { 04959 h++; 04960 continue; 04961 } 04962 msgbuf[t++] = msgbuf[h++]; 04963 lws = 1; 04964 continue; 04965 } 04966 msgbuf[t++] = msgbuf[h++]; 04967 if (lws) 04968 lws = 0; 04969 } 04970 msgbuf[t] = '\0'; 04971 return t; 04972 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Make our SIP dialog tag.
Definition at line 4586 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().
04587 { 04588 snprintf(tagbuf, len, "as%08lx", ast_random()); 04589 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10855 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().
10856 { 10857 const char *a[4]; 10858 const char *peer; 10859 int ret; 10860 10861 peer = astman_get_header(m,"Peer"); 10862 if (ast_strlen_zero(peer)) { 10863 astman_send_error(s, m, "Peer: <name> missing."); 10864 return 0; 10865 } 10866 a[0] = "sip"; 10867 a[1] = "show"; 10868 a[2] = "peer"; 10869 a[3] = peer; 10870 10871 ret = _sip_show_peer(1, -1, s, m, 4, a); 10872 astman_append(s, "\r\n\r\n" ); 10873 return ret; 10874 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10406 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().
10407 { 10408 const char *id = astman_get_header(m,"ActionID"); 10409 const char *a[] = {"sip", "show", "peers"}; 10410 char idtext[256] = ""; 10411 int total = 0; 10412 10413 if (!ast_strlen_zero(id)) 10414 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 10415 10416 astman_send_ack(s, m, "Peer status list will follow"); 10417 /* List the peers in separate manager events */ 10418 _sip_show_peers(-1, &total, s, m, 3, a); 10419 /* Send final confirmation */ 10420 astman_append(s, 10421 "Event: PeerlistComplete\r\n" 10422 "ListItems: %d\r\n" 10423 "%s" 10424 "\r\n", total, idtext); 10425 return 0; 10426 }
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 1692 of file chan_sip.c.
References sip_request::len, sip_methods, and text.
Referenced by __sip_autodestruct(), __sip_semi_ack(), and find_sip_method().
01693 { 01694 int len = strlen(sip_methods[id].text); 01695 int l_name = name ? strlen(name) : 0; 01696 /* true if the string is long enough, and ends with whitespace, and matches */ 01697 return (l_name >= len && name[len] < 33 && 01698 !strncasecmp(sip_methods[id].text, name, len)); 01699 }
static char * nat2str | ( | int | nat | ) | const [static] |
Convert NAT setting to text string.
Definition at line 10309 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().
10310 { 10311 switch(nat) { 10312 case SIP_NAT_NEVER: 10313 return "No"; 10314 case SIP_NAT_ROUTE: 10315 return "Route"; 10316 case SIP_NAT_ALWAYS: 10317 return "Always"; 10318 case SIP_NAT_RFC3581: 10319 return "RFC3581"; 10320 default: 10321 return "Unknown"; 10322 } 10323 }
static void parse_copy | ( | struct sip_request * | dst, | |
const struct sip_request * | src | |||
) | [static] |
Copy SIP request, parse it.
Definition at line 2286 of file chan_sip.c.
References sip_request::data, sip_request::len, and parse_request().
Referenced by send_request(), and send_response().
02287 { 02288 memset(dst, 0, sizeof(*dst)); 02289 memcpy(dst->data, src->data, sizeof(dst->data)); 02290 dst->len = src->len; 02291 parse_request(dst); 02292 }
static void parse_moved_contact | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Parse 302 Moved temporalily response.
Definition at line 12516 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().
12517 { 12518 char tmp[SIPBUFSIZE]; 12519 char *s, *e, *uri, *t; 12520 char *domain; 12521 12522 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 12523 if ((t = strchr(tmp, ','))) 12524 *t = '\0'; 12525 s = get_in_brackets(tmp); 12526 uri = ast_strdupa(s); 12527 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 12528 if (!strncasecmp(s, "sip:", 4)) 12529 s += 4; 12530 e = strchr(s, ';'); 12531 if (e) 12532 *e = '\0'; 12533 if (option_debug) 12534 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 12535 if (p->owner) 12536 ast_string_field_build(p->owner, call_forward, "SIP/%s", s); 12537 } else { 12538 e = strchr(tmp, '@'); 12539 if (e) { 12540 *e++ = '\0'; 12541 domain = e; 12542 } else { 12543 /* No username part */ 12544 domain = tmp; 12545 } 12546 e = strchr(s, ';'); /* Strip of parameters in the username part */ 12547 if (e) 12548 *e = '\0'; 12549 e = strchr(domain, ';'); /* Strip of parameters in the domain part */ 12550 if (e) 12551 *e = '\0'; 12552 12553 if (!strncasecmp(s, "sip:", 4)) 12554 s += 4; 12555 if (option_debug > 1) 12556 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 12557 if (p->owner) { 12558 pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri); 12559 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 12560 ast_string_field_set(p->owner, call_forward, s); 12561 } 12562 } 12563 }
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 8353 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().
08354 { 08355 char contact[SIPBUFSIZE]; 08356 char *c; 08357 08358 /* Look for brackets */ 08359 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08360 c = get_in_brackets(contact); 08361 08362 /* Save full contact to call pvt for later bye or re-invite */ 08363 ast_string_field_set(pvt, fullcontact, c); 08364 08365 /* Save URI for later ACKs, BYE or RE-invites */ 08366 ast_string_field_set(pvt, okcontacturi, c); 08367 08368 /* We should return false for URI:s we can't handle, 08369 like sips:, tel:, mailto:,ldap: etc */ 08370 return TRUE; 08371 }
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 8442 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_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_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_poke_peer(), SIP_REALTIME, SIPBUFSIZE, sip_pvt::sipoptions, sip_peer::sipoptions, STANDARD_SIP_PORT, sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3.
Referenced by register_verify().
08443 { 08444 char contact[SIPBUFSIZE]; 08445 char data[SIPBUFSIZE]; 08446 const char *expires = get_header(req, "Expires"); 08447 int expiry = atoi(expires); 08448 char *curi, *n, *pt; 08449 int port; 08450 const char *useragent; 08451 struct hostent *hp; 08452 struct ast_hostent ahp; 08453 struct sockaddr_in oldsin, testsin; 08454 08455 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08456 08457 if (ast_strlen_zero(expires)) { /* No expires header */ 08458 expires = strcasestr(contact, ";expires="); 08459 if (expires) { 08460 /* XXX bug here, we overwrite the string */ 08461 expires = strsep((char **) &expires, ";"); /* trim ; and beyond */ 08462 if (sscanf(expires + 9, "%30d", &expiry) != 1) 08463 expiry = default_expiry; 08464 } else { 08465 /* Nothing has been specified */ 08466 expiry = default_expiry; 08467 } 08468 } 08469 08470 /* Look for brackets */ 08471 curi = contact; 08472 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 08473 strsep(&curi, ";"); /* This is Header options, not URI options */ 08474 curi = get_in_brackets(contact); 08475 08476 /* if they did not specify Contact: or Expires:, they are querying 08477 what we currently have stored as their contact address, so return 08478 it 08479 */ 08480 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 08481 /* If we have an active registration, tell them when the registration is going to expire */ 08482 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 08483 pvt->expiry = ast_sched_when(sched, peer->expire); 08484 return PARSE_REGISTER_QUERY; 08485 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 08486 /* This means remove all registrations and return OK */ 08487 memset(&peer->addr, 0, sizeof(peer->addr)); 08488 if (!AST_SCHED_DEL(sched, peer->expire)) { 08489 struct sip_peer *peer_ptr = peer; 08490 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08491 } 08492 08493 destroy_association(peer); 08494 08495 register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */ 08496 peer->fullcontact[0] = '\0'; 08497 peer->useragent[0] = '\0'; 08498 peer->sipoptions = 0; 08499 peer->lastms = 0; 08500 pvt->expiry = 0; 08501 08502 if (option_verbose > 2) 08503 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name); 08504 08505 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name); 08506 return PARSE_REGISTER_UPDATE; 08507 } 08508 08509 /* Store whatever we got as a contact from the client */ 08510 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 08511 08512 /* For the 200 OK, we should use the received contact */ 08513 ast_string_field_build(pvt, our_contact, "<%s>", curi); 08514 08515 /* Make sure it's a SIP URL */ 08516 if (strncasecmp(curi, "sip:", 4)) { 08517 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 08518 } else 08519 curi += 4; 08520 /* Ditch q */ 08521 curi = strsep(&curi, ";"); 08522 /* Grab host */ 08523 n = strchr(curi, '@'); 08524 if (!n) { 08525 n = curi; 08526 curi = NULL; 08527 } else 08528 *n++ = '\0'; 08529 pt = strchr(n, ':'); 08530 if (pt) { 08531 *pt++ = '\0'; 08532 port = atoi(pt); 08533 } else 08534 port = STANDARD_SIP_PORT; 08535 oldsin = peer->addr; 08536 08537 /* Check that they're allowed to register at this IP */ 08538 /* XXX This could block for a long time XXX */ 08539 hp = ast_gethostbyname(n, &ahp); 08540 if (!hp) { 08541 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 08542 *peer->fullcontact = '\0'; 08543 ast_string_field_set(pvt, our_contact, ""); 08544 return PARSE_REGISTER_FAILED; 08545 } 08546 memcpy(&testsin.sin_addr, hp->h_addr, sizeof(testsin.sin_addr)); 08547 if ( ast_apply_ha(global_contact_ha, &testsin) != AST_SENSE_ALLOW || 08548 ast_apply_ha(peer->contactha, &testsin) != AST_SENSE_ALLOW) { 08549 ast_log(LOG_WARNING, "Host '%s' disallowed by rule\n", n); 08550 *peer->fullcontact = '\0'; 08551 ast_string_field_set(pvt, our_contact, ""); 08552 return PARSE_REGISTER_FAILED; 08553 } 08554 08555 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 08556 peer->addr.sin_family = AF_INET; 08557 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 08558 peer->addr.sin_port = htons(port); 08559 } else { 08560 /* Don't trust the contact field. Just use what they came to us 08561 with */ 08562 peer->addr = pvt->recv; 08563 } 08564 08565 /* Save SIP options profile */ 08566 peer->sipoptions = pvt->sipoptions; 08567 08568 if (curi && ast_strlen_zero(peer->username)) 08569 ast_copy_string(peer->username, curi, sizeof(peer->username)); 08570 08571 if (!AST_SCHED_DEL(sched, peer->expire)) { 08572 struct sip_peer *peer_ptr = peer; 08573 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08574 } 08575 if (expiry > max_expiry) 08576 expiry = max_expiry; 08577 if (expiry < min_expiry) 08578 expiry = min_expiry; 08579 if (ast_test_flag(&peer->flags[0], SIP_REALTIME) && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 08580 peer->expire = -1; 08581 } else { 08582 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08583 if (peer->expire == -1) { 08584 struct sip_peer *peer_ptr = peer; 08585 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08586 } 08587 } 08588 pvt->expiry = expiry; 08589 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); 08590 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08591 ast_db_put("SIP/Registry", peer->name, data); 08592 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08593 08594 /* Is this a new IP address for us? */ 08595 if (option_verbose > 2 && inaddrcmp(&peer->addr, &oldsin)) { 08596 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)); 08597 } 08598 sip_poke_peer(peer); 08599 register_peer_exten(peer, 1); 08600 08601 /* Save User agent */ 08602 useragent = get_header(req, "User-Agent"); 08603 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 08604 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 08605 if (option_verbose > 3) 08606 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 08607 } 08608 return PARSE_REGISTER_UPDATE; 08609 }
static int parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 4977 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().
04978 { 04979 /* Divide fields by NULL's */ 04980 char *c; 04981 int f = 0; 04982 04983 c = req->data; 04984 04985 /* First header starts immediately */ 04986 req->header[f] = c; 04987 while(*c) { 04988 if (*c == '\n') { 04989 /* We've got a new header */ 04990 *c = 0; 04991 04992 if (sipdebug && option_debug > 3) 04993 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04994 if (ast_strlen_zero(req->header[f])) { 04995 /* Line by itself means we're now in content */ 04996 c++; 04997 break; 04998 } 04999 if (f >= SIP_MAX_HEADERS - 1) { 05000 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 05001 } else { 05002 f++; 05003 req->header[f] = c + 1; 05004 } 05005 } else if (*c == '\r') { 05006 /* Ignore but eliminate \r's */ 05007 *c = 0; 05008 } 05009 c++; 05010 } 05011 05012 req->headers = f; 05013 05014 /* Check a non-newline-terminated last header */ 05015 if (!ast_strlen_zero(req->header[f])) { 05016 if (sipdebug && option_debug > 3) 05017 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 05018 req->headers++; 05019 } 05020 05021 /* Now we process any body content */ 05022 f = 0; 05023 req->line[f] = c; 05024 while (*c) { 05025 if (*c == '\n') { 05026 /* We've got a new line */ 05027 *c = 0; 05028 if (sipdebug && option_debug > 3) 05029 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 05030 if (f == SIP_MAX_LINES - 1) { 05031 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 05032 break; 05033 } else { 05034 f++; 05035 req->line[f] = c + 1; 05036 } 05037 } else if (*c == '\r') { 05038 /* Ignore and eliminate \r's */ 05039 *c = 0; 05040 } 05041 c++; 05042 } 05043 05044 req->lines = f; 05045 05046 /* Check a non-newline-terminated last line */ 05047 if (!ast_strlen_zero(req->line[f])) { 05048 req->lines++; 05049 } 05050 05051 if (*c) 05052 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 05053 05054 /* Split up the first line parts */ 05055 return determine_firstline_parts(req); 05056 }
static unsigned int parse_sip_options | ( | struct sip_pvt * | pvt, | |
const char * | supported | |||
) | [static] |
Parse supported header in incoming packet.
Definition at line 1716 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().
01717 { 01718 char *next, *sep; 01719 char *temp; 01720 unsigned int profile = 0; 01721 int i, found; 01722 01723 if (ast_strlen_zero(supported) ) 01724 return 0; 01725 temp = ast_strdupa(supported); 01726 01727 if (option_debug > 2 && sipdebug) 01728 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01729 01730 for (next = temp; next; next = sep) { 01731 found = FALSE; 01732 if ( (sep = strchr(next, ',')) != NULL) 01733 *sep++ = '\0'; 01734 next = ast_skip_blanks(next); 01735 if (option_debug > 2 && sipdebug) 01736 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01737 for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) { 01738 if (!strcasecmp(next, sip_options[i].text)) { 01739 profile |= sip_options[i].id; 01740 found = TRUE; 01741 if (option_debug > 2 && sipdebug) 01742 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01743 break; 01744 } 01745 } 01746 if (!found && option_debug > 2 && sipdebug) { 01747 if (!strncasecmp(next, "x-", 2)) 01748 ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next); 01749 else 01750 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01751 } 01752 } 01753 01754 if (pvt) 01755 pvt->sipoptions = profile; 01756 return profile; 01757 }
static int peer_status | ( | struct sip_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
Report Peer status in character string.
Definition at line 10328 of file chan_sip.c.
References ast_copy_string(), sip_peer::lastms, and sip_peer::maxms.
10329 { 10330 int res = 0; 10331 if (peer->maxms) { 10332 if (peer->lastms < 0) { 10333 ast_copy_string(status, "UNREACHABLE", statuslen); 10334 } else if (peer->lastms > peer->maxms) { 10335 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 10336 res = 1; 10337 } else if (peer->lastms) { 10338 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 10339 res = 1; 10340 } else { 10341 ast_copy_string(status, "UNKNOWN", statuslen); 10342 } 10343 } else { 10344 ast_copy_string(status, "Unmonitored", statuslen); 10345 /* Checking if port is 0 */ 10346 res = -1; 10347 } 10348 return res; 10349 }
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 10796 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().
10797 { 10798 int x, codec; 10799 10800 for(x = 0; x < 32 ; x++) { 10801 codec = ast_codec_pref_index(pref, x); 10802 if (!codec) 10803 break; 10804 ast_cli(fd, "%s", ast_getformatname(codec)); 10805 ast_cli(fd, ":%d", pref->framing[x]); 10806 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 10807 ast_cli(fd, ","); 10808 } 10809 if (!x) 10810 ast_cli(fd, "none"); 10811 }
static void print_group | ( | int | fd, | |
ast_group_t | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 10587 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
10588 { 10589 char buf[256]; 10590 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 10591 }
static void process_request_queue | ( | struct sip_pvt * | p, | |
int * | recount, | |||
int * | nounlock | |||
) | [static] |
Definition at line 16365 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().
16366 { 16367 struct sip_request *req; 16368 16369 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 16370 if (handle_request(p, req, &p->recv, recount, nounlock) == -1) { 16371 /* Request failed */ 16372 if (option_debug) { 16373 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 16374 } 16375 } 16376 ast_free(req); 16377 } 16378 }
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 5246 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, t38properties::direct, 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.
05247 { 05248 const char *m; /* SDP media offer */ 05249 const char *c; 05250 const char *a; 05251 char host[258]; 05252 int len = -1; 05253 int portno = -1; /*!< RTP Audio port number */ 05254 int vportno = -1; /*!< RTP Video port number */ 05255 int udptlportno = -1; 05256 int peert38capability = 0; 05257 char s[256]; 05258 int old = 0; 05259 05260 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 05261 int peercapability = 0, peernoncodeccapability = 0; 05262 int vpeercapability = 0, vpeernoncodeccapability = 0; 05263 struct sockaddr_in sin; /*!< media socket address */ 05264 struct sockaddr_in vsin; /*!< Video socket address */ 05265 05266 const char *codecs; 05267 struct hostent *hp; /*!< RTP Audio host IP */ 05268 struct hostent *vhp = NULL; /*!< RTP video host IP */ 05269 struct ast_hostent audiohp; 05270 struct ast_hostent videohp; 05271 int codec; 05272 int destiterator = 0; 05273 int iterator; 05274 int sendonly = -1; 05275 int numberofports; 05276 struct ast_rtp *newaudiortp, *newvideortp; /* Buffers for codec handling */ 05277 int newjointcapability; /* Negotiated capability */ 05278 int newpeercapability; 05279 int newnoncodeccapability; 05280 int numberofmediastreams = 0; 05281 int debug = sip_debug_test_pvt(p); 05282 05283 int found_rtpmap_codecs[SDP_MAX_RTPMAP_CODECS]; 05284 int last_rtpmap_codec=0; 05285 05286 if (!p->rtp) { 05287 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 05288 return -1; 05289 } 05290 05291 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 05292 #ifdef LOW_MEMORY 05293 newaudiortp = ast_threadstorage_get(&ts_audio_rtp, ast_rtp_alloc_size()); 05294 #else 05295 newaudiortp = alloca(ast_rtp_alloc_size()); 05296 #endif 05297 memset(newaudiortp, 0, ast_rtp_alloc_size()); 05298 ast_rtp_new_init(newaudiortp); 05299 ast_rtp_pt_clear(newaudiortp); 05300 05301 #ifdef LOW_MEMORY 05302 newvideortp = ast_threadstorage_get(&ts_video_rtp, ast_rtp_alloc_size()); 05303 #else 05304 newvideortp = alloca(ast_rtp_alloc_size()); 05305 #endif 05306 memset(newvideortp, 0, ast_rtp_alloc_size()); 05307 ast_rtp_new_init(newvideortp); 05308 ast_rtp_pt_clear(newvideortp); 05309 05310 /* Update our last rtprx when we receive an SDP, too */ 05311 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 05312 05313 05314 /* Try to find first media stream */ 05315 m = get_sdp(req, "m"); 05316 destiterator = req->sdp_start; 05317 c = get_sdp_iterate(&destiterator, req, "c"); 05318 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 05319 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 05320 return -1; 05321 } 05322 05323 /* Check for IPv4 address (not IPv6 yet) */ 05324 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05325 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 05326 return -1; 05327 } 05328 05329 /* XXX This could block for a long time, and block the main thread! XXX */ 05330 hp = ast_gethostbyname(host, &audiohp); 05331 if (!hp) { 05332 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 05333 return -1; 05334 } 05335 vhp = hp; /* Copy to video address as default too */ 05336 05337 iterator = req->sdp_start; 05338 ast_set_flag(&p->flags[0], SIP_NOVIDEO); 05339 05340 05341 /* Find media streams in this SDP offer */ 05342 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 05343 int x; 05344 int audio = FALSE; 05345 05346 numberofports = 1; 05347 len = -1; 05348 if ((sscanf(m, "audio %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05349 (sscanf(m, "audio %30d RTP/AVP %n", &x, &len) == 1 && len > 0)) { 05350 audio = TRUE; 05351 numberofmediastreams++; 05352 /* Found audio stream in this media definition */ 05353 portno = x; 05354 /* Scan through the RTP payload types specified in a "m=" line: */ 05355 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05356 if (sscanf(codecs, "%30d%n", &codec, &len) != 1) { 05357 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05358 return -1; 05359 } 05360 if (debug) 05361 ast_verbose("Found RTP audio format %d\n", codec); 05362 ast_rtp_set_m_type(newaudiortp, codec); 05363 } 05364 } else if ((sscanf(m, "video %30d/%30d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05365 (sscanf(m, "video %30d RTP/AVP %n", &x, &len) == 1 && len >= 0)) { 05366 /* If it is not audio - is it video ? */ 05367 ast_clear_flag(&p->flags[0], SIP_NOVIDEO); 05368 numberofmediastreams++; 05369 vportno = x; 05370 /* Scan through the RTP payload types specified in a "m=" line: */ 05371 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05372 if (sscanf(codecs, "%30d%n", &codec, &len) != 1) { 05373 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05374 return -1; 05375 } 05376 if (debug) 05377 ast_verbose("Found RTP video format %d\n", codec); 05378 ast_rtp_set_m_type(newvideortp, codec); 05379 } 05380 } else if (p->udptl && ( (sscanf(m, "image %30d udptl t38%n", &x, &len) == 1 && len > 0) || 05381 (sscanf(m, "image %30d UDPTL t38%n", &x, &len) == 1 && len >= 0) )) { 05382 if (debug) 05383 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 05384 udptlportno = x; 05385 numberofmediastreams++; 05386 05387 if (p->owner && p->lastinvite) { 05388 p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ 05389 if (option_debug > 1) 05390 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); 05391 } else { 05392 p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ 05393 p->t38.direct = 1; 05394 if (option_debug > 1) 05395 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05396 } 05397 } else 05398 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 05399 if (numberofports > 1) 05400 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 05401 05402 05403 /* Check for Media-description-level-address for audio */ 05404 c = get_sdp_iterate(&destiterator, req, "c"); 05405 if (!ast_strlen_zero(c)) { 05406 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05407 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 05408 } else { 05409 /* XXX This could block for a long time, and block the main thread! XXX */ 05410 if (audio) { 05411 if ( !(hp = ast_gethostbyname(host, &audiohp))) { 05412 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c); 05413 return -2; 05414 } 05415 } else if (!(vhp = ast_gethostbyname(host, &videohp))) { 05416 ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c); 05417 return -2; 05418 } 05419 } 05420 05421 } 05422 } 05423 if (portno == -1 && vportno == -1 && udptlportno == -1) 05424 /* No acceptable offer found in SDP - we have no ports */ 05425 /* Do not change RTP or VRTP if this is a re-invite */ 05426 return -2; 05427 05428 if (numberofmediastreams > 2) 05429 /* We have too many fax, audio and/or video media streams, fail this offer */ 05430 return -3; 05431 05432 /* RTP addresses and ports for audio and video */ 05433 sin.sin_family = AF_INET; 05434 vsin.sin_family = AF_INET; 05435 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 05436 if (vhp) 05437 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 05438 05439 /* Setup UDPTL port number */ 05440 if (p->udptl) { 05441 if (udptlportno > 0) { 05442 sin.sin_port = htons(udptlportno); 05443 if (ast_test_flag(&p->flags[0], SIP_NAT) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) { 05444 struct sockaddr_in peer; 05445 ast_rtp_get_peer(p->rtp, &peer); 05446 if (peer.sin_addr.s_addr) { 05447 memcpy(&sin.sin_addr, &peer.sin_addr, sizeof(sin.sin_addr)); 05448 if (debug) { 05449 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)); 05450 } 05451 } 05452 } 05453 ast_udptl_set_peer(p->udptl, &sin); 05454 if (debug) 05455 ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05456 } else { 05457 ast_udptl_stop(p->udptl); 05458 if (debug) 05459 ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n"); 05460 } 05461 } 05462 05463 05464 if (p->rtp) { 05465 if (portno > 0) { 05466 sin.sin_port = htons(portno); 05467 ast_rtp_set_peer(p->rtp, &sin); 05468 if (debug) 05469 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05470 } else { 05471 if (udptlportno > 0) { 05472 if (debug) 05473 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session. Callid %s\n", p->callid); 05474 } else { 05475 ast_rtp_stop(p->rtp); 05476 if (debug) 05477 ast_verbose("Peer doesn't provide audio. Callid %s\n", p->callid); 05478 } 05479 } 05480 } 05481 /* Setup video port number */ 05482 if (vportno != -1) 05483 vsin.sin_port = htons(vportno); 05484 05485 /* Next, scan through each "a=rtpmap:" line, noting each 05486 * specified RTP payload type (with corresponding MIME subtype): 05487 */ 05488 /* XXX This needs to be done per media stream, since it's media stream specific */ 05489 iterator = req->sdp_start; 05490 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05491 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 05492 if (option_debug > 1) { 05493 int breakout = FALSE; 05494 05495 /* If we're debugging, check for unsupported sdp options */ 05496 if (!strncasecmp(a, "rtcp:", (size_t) 5)) { 05497 if (debug) 05498 ast_verbose("Got unsupported a:rtcp in SDP offer \n"); 05499 breakout = TRUE; 05500 } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) { 05501 /* Format parameters: Not supported */ 05502 /* Note: This is used for codec parameters, like bitrate for 05503 G722 and video formats for H263 and H264 05504 See RFC2327 for an example */ 05505 if (debug) 05506 ast_verbose("Got unsupported a:fmtp in SDP offer \n"); 05507 breakout = TRUE; 05508 } else if (!strncasecmp(a, "framerate:", (size_t) 10)) { 05509 /* Video stuff: Not supported */ 05510 if (debug) 05511 ast_verbose("Got unsupported a:framerate in SDP offer \n"); 05512 breakout = TRUE; 05513 } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) { 05514 /* Video stuff: Not supported */ 05515 if (debug) 05516 ast_verbose("Got unsupported a:maxprate in SDP offer \n"); 05517 breakout = TRUE; 05518 } else if (!strncasecmp(a, "crypto:", (size_t) 7)) { 05519 /* SRTP stuff, not yet supported */ 05520 if (debug) 05521 ast_verbose("Got unsupported a:crypto in SDP offer \n"); 05522 breakout = TRUE; 05523 } 05524 if (breakout) /* We have a match, skip to next header */ 05525 continue; 05526 } 05527 if (!strcasecmp(a, "sendonly")) { 05528 if (sendonly == -1) 05529 sendonly = 1; 05530 continue; 05531 } else if (!strcasecmp(a, "inactive")) { 05532 if (sendonly == -1) 05533 sendonly = 2; 05534 continue; 05535 } else if (!strcasecmp(a, "sendrecv")) { 05536 if (sendonly == -1) 05537 sendonly = 0; 05538 continue; 05539 } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 05540 char *tmp = strrchr(a, ':'); 05541 long int framing = 0; 05542 if (tmp) { 05543 tmp++; 05544 framing = strtol(tmp, NULL, 10); 05545 if (framing == LONG_MIN || framing == LONG_MAX) { 05546 framing = 0; 05547 if (option_debug) 05548 ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a); 05549 } 05550 } 05551 if (framing && p->autoframing) { 05552 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 05553 int codec_n; 05554 int format = 0; 05555 for (codec_n = 0; codec_n < MAX_RTP_PT; codec_n++) { 05556 format = ast_rtp_codec_getformat(codec_n); 05557 if (!format) /* non-codec or not found */ 05558 continue; 05559 if (option_debug) 05560 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 05561 ast_codec_pref_setsize(pref, format, framing); 05562 } 05563 ast_rtp_codec_setpref(p->rtp, pref); 05564 } 05565 continue; 05566 } else if (sscanf(a, "rtpmap: %30u %[^/]/", &codec, mimeSubtype) == 2) { 05567 /* We have a rtpmap to handle */ 05568 int found = FALSE; 05569 /* We should propably check if this is an audio or video codec 05570 so we know where to look */ 05571 05572 if (last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 05573 /* Note: should really look at the 'freq' and '#chans' params too */ 05574 if(ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 05575 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) { 05576 if (debug) 05577 ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec); 05578 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05579 last_rtpmap_codec++; 05580 found = TRUE; 05581 05582 } else if (p->vrtp) { 05583 if(ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) { 05584 if (debug) 05585 ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec); 05586 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05587 last_rtpmap_codec++; 05588 found = TRUE; 05589 } 05590 } 05591 } else { 05592 if (debug) 05593 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 05594 } 05595 05596 if (!found) { 05597 /* Remove this codec since it's an unknown media type for us */ 05598 /* XXX This is buggy since the media line for audio and video can have the 05599 same numbers. We need to check as described above, but for testing this works... */ 05600 ast_rtp_unset_m_type(newaudiortp, codec); 05601 ast_rtp_unset_m_type(newvideortp, codec); 05602 if (debug) 05603 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 05604 } 05605 } 05606 } 05607 05608 if (udptlportno != -1) { 05609 int found = 0, x; 05610 05611 old = 0; 05612 05613 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 05614 iterator = req->sdp_start; 05615 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05616 if ((sscanf(a, "T38FaxMaxBuffer:%30d", &x) == 1)) { 05617 found = 1; 05618 if (option_debug > 2) 05619 ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x); 05620 } else if ((sscanf(a, "T38MaxBitRate:%30d", &x) == 1) || (sscanf(a, "T38FaxMaxRate:%30d", &x) == 1)) { 05621 found = 1; 05622 if (option_debug > 2) 05623 ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x); 05624 switch (x) { 05625 case 14400: 05626 peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05627 break; 05628 case 12000: 05629 peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05630 break; 05631 case 9600: 05632 peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05633 break; 05634 case 7200: 05635 peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05636 break; 05637 case 4800: 05638 peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 05639 break; 05640 case 2400: 05641 peert38capability |= T38FAX_RATE_2400; 05642 break; 05643 } 05644 } else if ((sscanf(a, "T38FaxVersion:%30d", &x) == 1)) { 05645 found = 1; 05646 if (option_debug > 2) 05647 ast_log(LOG_DEBUG, "FaxVersion: %d\n",x); 05648 if (x == 0) 05649 peert38capability |= T38FAX_VERSION_0; 05650 else if (x == 1) 05651 peert38capability |= T38FAX_VERSION_1; 05652 } else if ((sscanf(a, "T38FaxMaxDatagram:%30d", &x) == 1) || (sscanf(a, "T38MaxDatagram:%30d", &x) == 1)) { 05653 found = 1; 05654 if (option_debug > 2) 05655 ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x); 05656 ast_udptl_set_far_max_datagram(p->udptl, x); 05657 ast_udptl_set_local_max_datagram(p->udptl, x); 05658 } else if ((strncmp(a, "T38FaxFillBitRemoval", 20) == 0)) { 05659 found = 1; 05660 if ((sscanf(a, "T38FaxFillBitRemoval:%30d", &x) == 1)) { 05661 if (option_debug > 2) 05662 ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x); 05663 if (x == 1) 05664 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05665 } else { 05666 if (option_debug > 2) 05667 ast_log(LOG_DEBUG, "FillBitRemoval\n"); 05668 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05669 } 05670 } else if ((strncmp(a, "T38FaxTranscodingMMR", 20) == 0)) { 05671 found = 1; 05672 if ((sscanf(a, "T38FaxTranscodingMMR:%30d", &x) == 1)) { 05673 if (option_debug > 2) 05674 ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x); 05675 if (x == 1) 05676 peert38capability |= T38FAX_TRANSCODING_MMR; 05677 } else { 05678 if (option_debug > 2) 05679 ast_log(LOG_DEBUG, "Transcoding MMR\n"); 05680 peert38capability |= T38FAX_TRANSCODING_MMR; 05681 } 05682 } else if ((strncmp(a, "T38FaxTranscodingJBIG", 21) == 0)) { 05683 found = 1; 05684 if ((sscanf(a, "T38FaxTranscodingJBIG:%30d", &x) == 1)) { 05685 if (option_debug > 2) 05686 ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x); 05687 if (x == 1) 05688 peert38capability |= T38FAX_TRANSCODING_JBIG; 05689 } else { 05690 if (option_debug > 2) 05691 ast_log(LOG_DEBUG, "Transcoding JBIG\n"); 05692 peert38capability |= T38FAX_TRANSCODING_JBIG; 05693 } 05694 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 05695 found = 1; 05696 if (option_debug > 2) 05697 ast_log(LOG_DEBUG, "RateManagement: %s\n", s); 05698 if (!strcasecmp(s, "localTCF")) 05699 peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 05700 else if (!strcasecmp(s, "transferredTCF")) 05701 peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 05702 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 05703 found = 1; 05704 if (option_debug > 2) 05705 ast_log(LOG_DEBUG, "UDP EC: %s\n", s); 05706 if (!strcasecmp(s, "t38UDPRedundancy")) { 05707 peert38capability |= T38FAX_UDP_EC_REDUNDANCY; 05708 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 05709 } else if (!strcasecmp(s, "t38UDPFEC")) { 05710 peert38capability |= T38FAX_UDP_EC_FEC; 05711 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 05712 } else { 05713 peert38capability |= T38FAX_UDP_EC_NONE; 05714 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05715 } 05716 } 05717 } 05718 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 05719 p->t38.peercapability = peert38capability; 05720 p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */ 05721 peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 05722 p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */ 05723 } 05724 if (debug) 05725 ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 05726 p->t38.capability, 05727 p->t38.peercapability, 05728 p->t38.jointcapability); 05729 } else { 05730 p->t38.state = T38_DISABLED; 05731 if (option_debug > 2) 05732 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05733 } 05734 05735 /* Now gather all of the codecs that we are asked for: */ 05736 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 05737 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 05738 05739 newjointcapability = p->capability & (peercapability | vpeercapability); 05740 newpeercapability = (peercapability | vpeercapability); 05741 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 05742 05743 05744 if (debug) { 05745 /* shame on whoever coded this.... */ 05746 char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE]; 05747 05748 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 05749 ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability), 05750 ast_getformatname_multiple(s2, SIPBUFSIZE, newpeercapability), 05751 ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability), 05752 ast_getformatname_multiple(s4, SIPBUFSIZE, newjointcapability)); 05753 05754 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 05755 ast_rtp_lookup_mime_multiple(s1, SIPBUFSIZE, p->noncodeccapability, 0, 0), 05756 ast_rtp_lookup_mime_multiple(s2, SIPBUFSIZE, peernoncodeccapability, 0, 0), 05757 ast_rtp_lookup_mime_multiple(s3, SIPBUFSIZE, newnoncodeccapability, 0, 0)); 05758 } 05759 if (!newjointcapability) { 05760 /* If T.38 was not negotiated either, totally bail out... */ 05761 if (!p->t38.jointcapability || !udptlportno) { 05762 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 05763 /* Do NOT Change current setting */ 05764 return -1; 05765 } else { 05766 if (option_debug > 2) 05767 ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n"); 05768 return 0; 05769 } 05770 } 05771 05772 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 05773 they are acceptable */ 05774 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 05775 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 05776 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 05777 05778 ast_rtp_pt_copy(p->rtp, newaudiortp); 05779 if (p->vrtp) 05780 ast_rtp_pt_copy(p->vrtp, newvideortp); 05781 05782 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 05783 ast_clear_flag(&p->flags[0], SIP_DTMF); 05784 if (newnoncodeccapability & AST_RTP_DTMF) { 05785 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 05786 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 05787 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 05788 ast_rtp_setdtmf(p->rtp, 1); 05789 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05790 } else { 05791 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 05792 } 05793 } 05794 05795 /* Setup audio port number */ 05796 if (p->rtp && sin.sin_port) { 05797 ast_rtp_set_peer(p->rtp, &sin); 05798 if (debug) 05799 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05800 } 05801 05802 /* Setup video port number */ 05803 if (p->vrtp && vsin.sin_port) { 05804 ast_rtp_set_peer(p->vrtp, &vsin); 05805 if (debug) 05806 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 05807 } 05808 05809 /* Ok, we're going with this offer */ 05810 if (option_debug > 1) { 05811 char buf[SIPBUFSIZE]; 05812 ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability)); 05813 } 05814 05815 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 05816 return 0; 05817 05818 if (option_debug > 3) 05819 ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n"); 05820 05821 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05822 if (debug) { 05823 char s1[SIPBUFSIZE], s2[SIPBUFSIZE]; 05824 ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 05825 ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability), 05826 ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats)); 05827 } 05828 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); 05829 ast_set_read_format(p->owner, p->owner->readformat); 05830 ast_set_write_format(p->owner, p->owner->writeformat); 05831 } 05832 05833 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 05834 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 05835 /* Activate a re-invite */ 05836 ast_queue_frame(p->owner, &ast_null_frame); 05837 } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { 05838 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 05839 S_OR(p->mohsuggest, NULL), 05840 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 05841 if (sendonly) 05842 ast_rtp_stop(p->rtp); 05843 /* RTCP needs to go ahead, even if we're on hold!!! */ 05844 /* Activate a re-invite */ 05845 ast_queue_frame(p->owner, &ast_null_frame); 05846 } 05847 05848 /* Manager Hold and Unhold events must be generated, if necessary */ 05849 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) 05850 change_hold_state(p, req, FALSE, sendonly); 05851 else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) 05852 change_hold_state(p, req, TRUE, sendonly); 05853 return 0; 05854 }
static int queue_request | ( | struct sip_pvt * | p, | |
const struct sip_request * | req | |||
) | [static] |
Definition at line 16430 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().
16431 { 16432 struct sip_request *newreq; 16433 16434 if (!(newreq = ast_calloc(1, sizeof(*newreq)))) { 16435 return -1; 16436 } 16437 16438 copy_request(newreq, req); 16439 AST_LIST_INSERT_TAIL(&p->request_queue, newreq, next); 16440 if (p->request_queue_sched_id == -1) { 16441 p->request_queue_sched_id = ast_sched_add(sched, 10, scheduler_process_request_queue, p); 16442 } 16443 16444 return 0; 16445 }
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 2563 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.
02564 { 02565 struct sip_peer *peer=NULL; 02566 struct ast_variable *var = NULL; 02567 struct ast_config *peerlist = NULL; 02568 struct ast_variable *tmp; 02569 struct ast_flags flags = {0}; 02570 const char *iabuf = NULL; 02571 char portstring[6]; /*up to five digits plus null terminator*/ 02572 const char *insecure; 02573 char *cat = NULL; 02574 unsigned short portnum; 02575 02576 /* First check on peer name */ 02577 if (newpeername) { 02578 var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL); 02579 if (!var && sin) 02580 var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02581 if (!var) { 02582 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 02583 /*!\note 02584 * If this one loaded something, then we need to ensure that the host 02585 * field matched. The only reason why we can't have this as a criteria 02586 * is because we only have the IP address and the host field might be 02587 * set as a name (and the reverse PTR might not match). 02588 */ 02589 if (var && sin) { 02590 for (tmp = var; tmp; tmp = tmp->next) { 02591 if (!strcasecmp(tmp->name, "host")) { 02592 struct hostent *hp; 02593 struct ast_hostent ahp; 02594 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02595 /* No match */ 02596 ast_variables_destroy(var); 02597 var = NULL; 02598 } 02599 break; 02600 } 02601 } 02602 } 02603 } 02604 } 02605 02606 if (!var && sin) { /* Then check on IP address */ 02607 iabuf = ast_inet_ntoa(sin->sin_addr); 02608 portnum = ntohs(sin->sin_port); 02609 sprintf(portstring, "%d", portnum); 02610 var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */ 02611 if (!var) 02612 var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL); /* Then check for registered hosts */ 02613 if (!var) { 02614 peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/ 02615 if(peerlist){ 02616 while((cat = ast_category_browse(peerlist, cat))) 02617 { 02618 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02619 set_insecure_flags(&flags, insecure, -1); 02620 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02621 var = ast_category_root(peerlist, cat); 02622 break; 02623 } 02624 } 02625 } 02626 if(!var) { 02627 ast_config_destroy(peerlist); 02628 peerlist = NULL; /*for safety's sake*/ 02629 cat = NULL; 02630 peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/ 02631 if(peerlist) { 02632 while((cat = ast_category_browse(peerlist, cat))) 02633 { 02634 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02635 set_insecure_flags(&flags, insecure, -1); 02636 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02637 var = ast_category_root(peerlist, cat); 02638 break; 02639 } 02640 } 02641 } 02642 } 02643 } 02644 } 02645 02646 if (!var) { 02647 if(peerlist) 02648 ast_config_destroy(peerlist); 02649 return NULL; 02650 } 02651 02652 for (tmp = var; tmp; tmp = tmp->next) { 02653 /* If this is type=user, then skip this object. */ 02654 if (!strcasecmp(tmp->name, "type") && 02655 !strcasecmp(tmp->value, "user")) { 02656 ast_variables_destroy(var); 02657 return NULL; 02658 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 02659 newpeername = tmp->value; 02660 } else if (!strcasecmp(tmp->name, "lastms")) { 02661 seen_lastms = 1; 02662 } 02663 } 02664 02665 if (!newpeername) { /* Did not find peer in realtime */ 02666 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); 02667 if(peerlist) 02668 ast_config_destroy(peerlist); 02669 else 02670 ast_variables_destroy(var); 02671 return NULL; 02672 } 02673 02674 /* Peer found in realtime, now build it in memory */ 02675 peer = build_peer(newpeername, var, NULL, 1); 02676 if (!peer) { 02677 if(peerlist) 02678 ast_config_destroy(peerlist); 02679 else 02680 ast_variables_destroy(var); 02681 return NULL; 02682 } 02683 02684 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) { 02685 /* Cache peer */ 02686 ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 02687 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 02688 if (!AST_SCHED_DEL(sched, peer->expire)) { 02689 struct sip_peer *peer_ptr = peer; 02690 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02691 } 02692 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, ASTOBJ_REF(peer)); 02693 if (peer->expire == -1) { 02694 struct sip_peer *peer_ptr = peer; 02695 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02696 } 02697 } 02698 ASTOBJ_CONTAINER_LINK(&peerl,peer); 02699 } 02700 ast_set_flag(&peer->flags[0], SIP_REALTIME); 02701 if(peerlist) 02702 ast_config_destroy(peerlist); 02703 else 02704 ast_variables_destroy(var); 02705 return peer; 02706 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
const char * | username, | |||
const char * | fullcontact, | |||
int | expirey, | |||
int | lastms | |||
) | [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 2442 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.
02443 { 02444 char port[10]; 02445 char ipaddr[INET_ADDRSTRLEN]; 02446 char regseconds[20]; 02447 char str_lastms[20]; 02448 02449 char *sysname = ast_config_AST_SYSTEM_NAME; 02450 char *syslabel = NULL; 02451 02452 time_t nowtime = time(NULL) + expirey; 02453 const char *fc = fullcontact ? "fullcontact" : NULL; 02454 02455 snprintf(str_lastms, sizeof(str_lastms), "%d", lastms); 02456 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 02457 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 02458 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02459 02460 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 02461 sysname = NULL; 02462 else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME)) 02463 syslabel = "regserver"; 02464 02465 if (fc) 02466 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02467 "port", port, "regseconds", regseconds, 02468 "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */ 02469 else 02470 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02471 "port", port, "regseconds", regseconds, 02472 "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */ 02473 if (seen_lastms) { 02474 /* We cannot do this in the same statement as above, because the lack of 02475 * this field could cause the whole statement to fail. */ 02476 ast_update_realtime("sippeers", "name", peername, "lastms", str_lastms, NULL); 02477 } 02478 }
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 2756 of file chan_sip.c.
References ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, ast_variable::value, and var.
02757 { 02758 struct ast_variable *var; 02759 struct ast_variable *tmp; 02760 struct sip_user *user = NULL; 02761 02762 var = ast_load_realtime("sipusers", "name", username, NULL); 02763 02764 if (!var) 02765 return NULL; 02766 02767 for (tmp = var; tmp; tmp = tmp->next) { 02768 if (!strcasecmp(tmp->name, "type") && 02769 !strcasecmp(tmp->value, "peer")) { 02770 ast_variables_destroy(var); 02771 return NULL; 02772 } 02773 } 02774 02775 user = build_user(username, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02776 02777 if (!user) { /* No user found */ 02778 ast_variables_destroy(var); 02779 return NULL; 02780 } 02781 02782 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02783 ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02784 suserobjs++; 02785 ASTOBJ_CONTAINER_LINK(&userl,user); 02786 } else { 02787 /* Move counter from s to r... */ 02788 suserobjs--; 02789 ruserobjs++; 02790 } 02791 ast_set_flag(&user->flags[0], SIP_REALTIME); 02792 ast_variables_destroy(var); 02793 return user; 02794 }
static void receive_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 10211 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().
10212 { 10213 char buf[1024]; 10214 struct ast_frame f; 10215 const char *content_type = get_header(req, "Content-Type"); 10216 10217 if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */ 10218 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 10219 if (!p->owner) 10220 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10221 return; 10222 } 10223 10224 if (get_msg_text(buf, sizeof(buf), req)) { 10225 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 10226 transmit_response(p, "202 Accepted", req); 10227 if (!p->owner) 10228 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10229 return; 10230 } 10231 10232 if (p->owner) { 10233 if (sip_debug_test_pvt(p)) 10234 ast_verbose("Message received: '%s'\n", buf); 10235 memset(&f, 0, sizeof(f)); 10236 f.frametype = AST_FRAME_TEXT; 10237 f.subclass = 0; 10238 f.offset = 0; 10239 f.data = buf; 10240 f.datalen = strlen(buf); 10241 ast_queue_frame(p->owner, &f); 10242 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 10243 } else { /* Message outside of a call, we do not support that */ 10244 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); 10245 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 10246 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10247 } 10248 return; 10249 }
static char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 1651 of file chan_sip.c.
References referstatusstrings, and text.
Referenced by __sip_show_channels().
01652 { 01653 int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0])); 01654 int x; 01655 01656 for (x = 0; x < i; x++) { 01657 if (referstatusstrings[x].status == rstatus) 01658 return (char *) referstatusstrings[x].text; 01659 } 01660 return ""; 01661 }
static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 8281 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, TRUE, sip_peer::username, and username.
08282 { 08283 char data[256]; 08284 struct in_addr in; 08285 int expiry; 08286 int port; 08287 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 08288 08289 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08290 return; 08291 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 08292 return; 08293 08294 scan = data; 08295 addr = strsep(&scan, ":"); 08296 port_str = strsep(&scan, ":"); 08297 expiry_str = strsep(&scan, ":"); 08298 username = strsep(&scan, ":"); 08299 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 08300 08301 if (!inet_aton(addr, &in)) 08302 return; 08303 08304 if (port_str) 08305 port = atoi(port_str); 08306 else 08307 return; 08308 08309 if (expiry_str) 08310 expiry = atoi(expiry_str); 08311 else 08312 return; 08313 08314 if (username) 08315 ast_copy_string(peer->username, username, sizeof(peer->username)); 08316 if (contact) 08317 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 08318 08319 if (option_debug > 1) 08320 ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 08321 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 08322 08323 memset(&peer->addr, 0, sizeof(peer->addr)); 08324 peer->addr.sin_family = AF_INET; 08325 peer->addr.sin_addr = in; 08326 peer->addr.sin_port = htons(port); 08327 if (sipsock < 0) { 08328 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 08329 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 08330 struct sip_peer *peer_ptr = peer; 08331 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08332 } 08333 peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, ASTOBJ_REF(peer)); 08334 if (peer->pokeexpire == -1) { 08335 struct sip_peer *peer_ptr = peer; 08336 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08337 } 08338 } else 08339 sip_poke_peer(peer); 08340 if (!AST_SCHED_DEL(sched, peer->expire)) { 08341 struct sip_peer *peer_ptr = peer; 08342 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08343 } 08344 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08345 if (peer->expire == -1) { 08346 struct sip_peer *peer_ptr = peer; 08347 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08348 } 08349 register_peer_exten(peer, TRUE); 08350 }
static void register_peer_exten | ( | struct sip_peer * | peer, | |
int | onoff | |||
) | [static] |
Automatically add peer extension to dial plan.
Definition at line 2481 of file chan_sip.c.
References ast_add_extension(), ast_context_find(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free_ptr, ast_log(), ast_strdup, ast_strlen_zero(), context, ext, LOG_WARNING, sip_peer::name, sip_peer::regexten, and S_OR.
02482 { 02483 char multi[256]; 02484 char *stringp, *ext, *context; 02485 02486 /* XXX note that global_regcontext is both a global 'enable' flag and 02487 * the name of the global regexten context, if not specified 02488 * individually. 02489 */ 02490 if (ast_strlen_zero(global_regcontext)) 02491 return; 02492 02493 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 02494 stringp = multi; 02495 while ((ext = strsep(&stringp, "&"))) { 02496 if ((context = strchr(ext, '@'))) { 02497 *context++ = '\0'; /* split ext@context */ 02498 if (!ast_context_find(context)) { 02499 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 02500 continue; 02501 } 02502 } else { 02503 context = global_regcontext; 02504 } 02505 if (onoff) { 02506 if (!ast_exists_extension(NULL, context, ext, 1, NULL)) { 02507 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 02508 ast_strdup(peer->name), ast_free_ptr, "SIP"); 02509 } 02510 } else { 02511 ast_context_remove_extension(context, ext, 1, NULL); 02512 } 02513 } 02514 }
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 9100 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.
09102 { 09103 enum check_auth_result res = AUTH_NOT_FOUND; 09104 struct sip_peer *peer; 09105 char tmp[256]; 09106 char *name, *c; 09107 char *t; 09108 char *domain; 09109 09110 /* Terminate URI */ 09111 t = uri; 09112 while(*t && (*t > 32) && (*t != ';')) 09113 t++; 09114 *t = '\0'; 09115 09116 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 09117 if (pedanticsipchecking) 09118 ast_uri_decode(tmp); 09119 09120 c = get_in_brackets(tmp); 09121 c = strsep(&c, ";"); /* Ditch ;user=phone */ 09122 09123 if (!strncasecmp(c, "sip:", 4)) { 09124 name = c + 4; 09125 } else { 09126 name = c; 09127 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 09128 } 09129 09130 /* Strip off the domain name */ 09131 if ((c = strchr(name, '@'))) { 09132 *c++ = '\0'; 09133 domain = c; 09134 if ((c = strchr(domain, ':'))) /* Remove :port */ 09135 *c = '\0'; 09136 if (!AST_LIST_EMPTY(&domain_list)) { 09137 if (!check_sip_domain(domain, NULL, 0)) { 09138 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 09139 return AUTH_UNKNOWN_DOMAIN; 09140 } 09141 } 09142 } 09143 09144 ast_string_field_set(p, exten, name); 09145 build_contact(p); 09146 peer = find_peer(name, NULL, 1, 0); 09147 if (!(peer && ast_apply_ha(peer->ha, sin))) { 09148 /* Peer fails ACL check */ 09149 if (peer) { 09150 ASTOBJ_UNREF(peer, sip_destroy_peer); 09151 res = AUTH_ACL_FAILED; 09152 } else 09153 res = AUTH_NOT_FOUND; 09154 } 09155 if (peer) { 09156 /* Set Frame packetization */ 09157 if (p->rtp) { 09158 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09159 p->autoframing = peer->autoframing; 09160 } 09161 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 09162 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 09163 res = AUTH_PEER_NOT_DYNAMIC; 09164 } else { 09165 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 09166 transmit_response(p, "100 Trying", req); 09167 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09168 if (sip_cancel_destroy(p)) 09169 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09170 09171 /* We have a succesful registration attemp with proper authentication, 09172 now, update the peer */ 09173 switch (parse_register_contact(p, peer, req)) { 09174 case PARSE_REGISTER_FAILED: 09175 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 09176 transmit_response_with_date(p, "400 Bad Request", req); 09177 peer->lastmsgssent = -1; 09178 res = 0; 09179 break; 09180 case PARSE_REGISTER_QUERY: 09181 transmit_response_with_date(p, "200 OK", req); 09182 peer->lastmsgssent = -1; 09183 res = 0; 09184 break; 09185 case PARSE_REGISTER_UPDATE: 09186 update_peer(peer, p->expiry); 09187 /* Say OK and ask subsystem to retransmit msg counter */ 09188 transmit_response_with_date(p, "200 OK", req); 09189 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 09190 peer->lastmsgssent = -1; 09191 res = 0; 09192 break; 09193 } 09194 } 09195 } 09196 } 09197 if (!peer && autocreatepeer) { 09198 /* Create peer if we have autocreate mode enabled */ 09199 peer = temp_peer(name); 09200 if (peer) { 09201 ASTOBJ_CONTAINER_LINK(&peerl, peer); 09202 if (sip_cancel_destroy(p)) 09203 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09204 switch (parse_register_contact(p, peer, req)) { 09205 case PARSE_REGISTER_FAILED: 09206 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 09207 transmit_response_with_date(p, "400 Bad Request", req); 09208 peer->lastmsgssent = -1; 09209 res = 0; 09210 break; 09211 case PARSE_REGISTER_QUERY: 09212 transmit_response_with_date(p, "200 OK", req); 09213 peer->lastmsgssent = -1; 09214 res = 0; 09215 break; 09216 case PARSE_REGISTER_UPDATE: 09217 /* Say OK and ask subsystem to retransmit msg counter */ 09218 transmit_response_with_date(p, "200 OK", req); 09219 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 09220 peer->lastmsgssent = -1; 09221 res = 0; 09222 break; 09223 } 09224 } 09225 } 09226 if (!peer && global_alwaysauthreject) { 09227 /* If we found a peer, we transmit a 100 Trying. Therefore, if we're 09228 * trying to avoid leaking information, we MUST also transmit the same 09229 * response when we DON'T find a peer. */ 09230 transmit_response(p, "100 Trying", req); 09231 /* Insert a fake delay between the 100 and the subsequent failure. */ 09232 sched_yield(); 09233 } 09234 if (!res) { 09235 ast_device_state_changed("SIP/%s", peer->name); 09236 } 09237 if (res < 0) { 09238 switch (res) { 09239 case AUTH_SECRET_FAILED: 09240 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 09241 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 09242 break; 09243 case AUTH_USERNAME_MISMATCH: 09244 /* Username and digest username does not match. 09245 Asterisk uses the From: username for authentication. We need the 09246 users to use the same authentication user name until we support 09247 proper authentication by digest auth name */ 09248 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 09249 break; 09250 case AUTH_NOT_FOUND: 09251 case AUTH_PEER_NOT_DYNAMIC: 09252 case AUTH_ACL_FAILED: 09253 if (global_alwaysauthreject) { 09254 transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE); 09255 } else { 09256 /* URI not found */ 09257 if (res == AUTH_PEER_NOT_DYNAMIC) 09258 transmit_response(p, "403 Forbidden", &p->initreq); 09259 else 09260 transmit_response(p, "404 Not found", &p->initreq); 09261 } 09262 break; 09263 default: 09264 break; 09265 } 09266 } 09267 if (peer) 09268 ASTOBJ_UNREF(peer, sip_destroy_peer); 09269 09270 return res; 09271 }
static char * regstate2str | ( | enum sipregistrystate | regstate | ) | const [static] |
Convert registration state status to string.
Definition at line 7751 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.
07752 { 07753 switch(regstate) { 07754 case REG_STATE_FAILED: 07755 return "Failed"; 07756 case REG_STATE_UNREGISTERED: 07757 return "Unregistered"; 07758 case REG_STATE_REGSENT: 07759 return "Request Sent"; 07760 case REG_STATE_AUTHSENT: 07761 return "Auth. Sent"; 07762 case REG_STATE_REGISTERED: 07763 return "Registered"; 07764 case REG_STATE_REJECTED: 07765 return "Rejected"; 07766 case REG_STATE_TIMEOUT: 07767 return "Timeout"; 07768 case REG_STATE_NOAUTH: 07769 return "No Authentication"; 07770 default: 07771 return "Unknown"; 07772 } 07773 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 19081 of file chan_sip.c.
References sip_reload().
19082 { 19083 return sip_reload(0, 0, NULL); 19084 }
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 17963 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().
17964 { 17965 struct ast_config *cfg, *ucfg; 17966 struct ast_variable *v; 17967 struct sip_peer *peer; 17968 struct sip_user *user; 17969 struct ast_hostent ahp; 17970 char *cat, *stringp, *context, *oldregcontext; 17971 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 17972 struct hostent *hp; 17973 int format; 17974 struct ast_flags dummy[2]; 17975 int auto_sip_domains = FALSE; 17976 struct sockaddr_in old_bindaddr = bindaddr; 17977 int registry_count = 0, peer_count = 0, user_count = 0; 17978 unsigned int temp_tos = 0; 17979 struct ast_flags debugflag = {0}; 17980 17981 cfg = ast_config_load(config); 17982 17983 /* We *must* have a config file otherwise stop immediately */ 17984 if (!cfg) { 17985 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 17986 return -1; 17987 } 17988 17989 if (option_debug > 3) 17990 ast_log(LOG_DEBUG, "--------------- SIP reload started\n"); 17991 17992 clear_realm_authentication(authl); 17993 clear_sip_domains(); 17994 authl = NULL; 17995 17996 ast_free_ha(global_contact_ha); 17997 global_contact_ha = NULL; 17998 17999 /* First, destroy all outstanding registry calls */ 18000 /* This is needed, since otherwise active registry entries will not be destroyed */ 18001 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 18002 ASTOBJ_RDLOCK(iterator); 18003 if (iterator->call) { 18004 if (option_debug > 2) 18005 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 18006 /* This will also remove references to the registry */ 18007 sip_destroy(iterator->call); 18008 } 18009 ASTOBJ_UNLOCK(iterator); 18010 18011 } while(0)); 18012 18013 /* Then, actually destroy users and registry */ 18014 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 18015 if (option_debug > 3) 18016 ast_log(LOG_DEBUG, "--------------- Done destroying user list\n"); 18017 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 18018 if (option_debug > 3) 18019 ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n"); 18020 ASTOBJ_CONTAINER_MARKALL(&peerl); 18021 18022 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 18023 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 18024 oldregcontext = oldcontexts; 18025 18026 /* Clear all flags before setting default values */ 18027 /* Preserve debugging settings for console */ 18028 ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 18029 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 18030 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 18031 ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE); 18032 18033 /* Reset IP addresses */ 18034 memset(&bindaddr, 0, sizeof(bindaddr)); 18035 ast_free_ha(localaddr); 18036 memset(&localaddr, 0, sizeof(localaddr)); 18037 memset(&externip, 0, sizeof(externip)); 18038 memset(&default_prefs, 0 , sizeof(default_prefs)); 18039 outboundproxyip.sin_port = htons(STANDARD_SIP_PORT); 18040 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 18041 ourport = STANDARD_SIP_PORT; 18042 srvlookup = DEFAULT_SRVLOOKUP; 18043 global_tos_sip = DEFAULT_TOS_SIP; 18044 global_tos_audio = DEFAULT_TOS_AUDIO; 18045 global_tos_video = DEFAULT_TOS_VIDEO; 18046 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 18047 externexpire = 0; /* Expiration for DNS re-issuing */ 18048 externrefresh = 10; 18049 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 18050 18051 /* Reset channel settings to default before re-configuring */ 18052 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 18053 global_regcontext[0] = '\0'; 18054 expiry = DEFAULT_EXPIRY; 18055 global_notifyringing = DEFAULT_NOTIFYRINGING; 18056 global_limitonpeers = FALSE; 18057 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 18058 global_notifyhold = FALSE; 18059 global_alwaysauthreject = 0; 18060 global_allowsubscribe = FALSE; 18061 ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent)); 18062 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 18063 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) 18064 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 18065 else 18066 ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm)); 18067 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 18068 compactheaders = DEFAULT_COMPACTHEADERS; 18069 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 18070 global_regattempts_max = 0; 18071 pedanticsipchecking = DEFAULT_PEDANTIC; 18072 global_mwitime = DEFAULT_MWITIME; 18073 autocreatepeer = DEFAULT_AUTOCREATEPEER; 18074 global_autoframing = 0; 18075 global_allowguest = DEFAULT_ALLOWGUEST; 18076 global_rtptimeout = 0; 18077 global_rtpholdtimeout = 0; 18078 global_rtpkeepalive = 0; 18079 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 18080 global_rtautoclear = 120; 18081 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 18082 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 18083 ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE); 18084 18085 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 18086 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 18087 default_subscribecontext[0] = '\0'; 18088 default_language[0] = '\0'; 18089 default_fromdomain[0] = '\0'; 18090 default_qualify = DEFAULT_QUALIFY; 18091 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 18092 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 18093 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 18094 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 18095 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 18096 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 18097 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 18098 18099 /* Debugging settings, always default to off */ 18100 dumphistory = FALSE; 18101 recordhistory = FALSE; 18102 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 18103 18104 /* Misc settings for the channel */ 18105 global_relaxdtmf = FALSE; 18106 global_callevents = FALSE; 18107 global_t1min = DEFAULT_T1MIN; 18108 18109 global_matchexterniplocally = FALSE; 18110 18111 /* Copy the default jb config over global_jbconf */ 18112 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 18113 18114 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 18115 18116 /* Read the [general] config section of sip.conf (or from realtime config) */ 18117 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 18118 if (handle_common_options(&global_flags[0], &dummy[0], v)) 18119 continue; 18120 /* handle jb conf */ 18121 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 18122 continue; 18123 18124 /* Create the interface list */ 18125 if (!strcasecmp(v->name, "context")) { 18126 ast_copy_string(default_context, v->value, sizeof(default_context)); 18127 } else if (!strcasecmp(v->name, "subscribecontext")) { 18128 ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext)); 18129 } else if (!strcasecmp(v->name, "allowguest")) { 18130 global_allowguest = ast_true(v->value) ? 1 : 0; 18131 } else if (!strcasecmp(v->name, "realm")) { 18132 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 18133 } else if (!strcasecmp(v->name, "useragent")) { 18134 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 18135 if (option_debug) 18136 ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 18137 } else if (!strcasecmp(v->name, "allowtransfer")) { 18138 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 18139 } else if (!strcasecmp(v->name, "rtcachefriends")) { 18140 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 18141 } else if (!strcasecmp(v->name, "rtsavesysname")) { 18142 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME); 18143 } else if (!strcasecmp(v->name, "rtupdate")) { 18144 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE); 18145 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 18146 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 18147 } else if (!strcasecmp(v->name, "t1min")) { 18148 global_t1min = atoi(v->value); 18149 } else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) { 18150 global_dynamic_exclude_static = ast_true(v->value); 18151 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 18152 global_contact_ha = ast_append_ha(v->name + 7, v->value, global_contact_ha); 18153 } else if (!strcasecmp(v->name, "rtautoclear")) { 18154 int i = atoi(v->value); 18155 if (i > 0) 18156 global_rtautoclear = i; 18157 else 18158 i = 0; 18159 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 18160 } else if (!strcasecmp(v->name, "usereqphone")) { 18161 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 18162 } else if (!strcasecmp(v->name, "relaxdtmf")) { 18163 global_relaxdtmf = ast_true(v->value); 18164 } else if (!strcasecmp(v->name, "checkmwi")) { 18165 if ((sscanf(v->value, "%30d", &global_mwitime) != 1) || (global_mwitime < 0)) { 18166 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 18167 global_mwitime = DEFAULT_MWITIME; 18168 } 18169 } else if (!strcasecmp(v->name, "vmexten")) { 18170 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 18171 } else if (!strcasecmp(v->name, "rtptimeout")) { 18172 if ((sscanf(v->value, "%30d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 18173 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 18174 global_rtptimeout = 0; 18175 } 18176 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 18177 if ((sscanf(v->value, "%30d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 18178 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 18179 global_rtpholdtimeout = 0; 18180 } 18181 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 18182 if ((sscanf(v->value, "%30d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 18183 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 18184 global_rtpkeepalive = 0; 18185 } 18186 } else if (!strcasecmp(v->name, "compactheaders")) { 18187 compactheaders = ast_true(v->value); 18188 } else if (!strcasecmp(v->name, "notifymimetype")) { 18189 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 18190 } else if (!strncasecmp(v->name, "limitonpeer", 11)) { 18191 global_limitonpeers = ast_true(v->value); 18192 } else if (!strcasecmp(v->name, "directrtpsetup")) { 18193 global_directrtpsetup = ast_true(v->value); 18194 } else if (!strcasecmp(v->name, "notifyringing")) { 18195 global_notifyringing = ast_true(v->value); 18196 } else if (!strcasecmp(v->name, "notifyhold")) { 18197 global_notifyhold = ast_true(v->value); 18198 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 18199 global_alwaysauthreject = ast_true(v->value); 18200 } else if (!strcasecmp(v->name, "mohinterpret") 18201 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 18202 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 18203 } else if (!strcasecmp(v->name, "mohsuggest")) { 18204 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 18205 } else if (!strcasecmp(v->name, "language")) { 18206 ast_copy_string(default_language, v->value, sizeof(default_language)); 18207 } else if (!strcasecmp(v->name, "regcontext")) { 18208 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 18209 stringp = newcontexts; 18210 /* Let's remove any contexts that are no longer defined in regcontext */ 18211 cleanup_stale_contexts(stringp, oldregcontext); 18212 /* Create contexts if they don't exist already */ 18213 while ((context = strsep(&stringp, "&"))) { 18214 if (!ast_context_find(context)) 18215 ast_context_create(NULL, context,"SIP"); 18216 } 18217 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 18218 } else if (!strcasecmp(v->name, "callerid")) { 18219 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 18220 } else if (!strcasecmp(v->name, "fromdomain")) { 18221 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 18222 } else if (!strcasecmp(v->name, "outboundproxy")) { 18223 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 18224 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 18225 } else if (!strcasecmp(v->name, "outboundproxyport")) { 18226 /* Port needs to be after IP */ 18227 sscanf(v->value, "%30d", &format); 18228 outboundproxyip.sin_port = htons(format); 18229 } else if (!strcasecmp(v->name, "autocreatepeer")) { 18230 autocreatepeer = ast_true(v->value); 18231 } else if (!strcasecmp(v->name, "srvlookup")) { 18232 srvlookup = ast_true(v->value); 18233 } else if (!strcasecmp(v->name, "pedantic")) { 18234 pedanticsipchecking = ast_true(v->value); 18235 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 18236 max_expiry = atoi(v->value); 18237 if (max_expiry < 1) 18238 max_expiry = DEFAULT_MAX_EXPIRY; 18239 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 18240 min_expiry = atoi(v->value); 18241 if (min_expiry < 1) 18242 min_expiry = DEFAULT_MIN_EXPIRY; 18243 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 18244 default_expiry = atoi(v->value); 18245 if (default_expiry < 1) 18246 default_expiry = DEFAULT_DEFAULT_EXPIRY; 18247 } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */ 18248 if (ast_true(v->value)) 18249 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 18250 } else if (!strcasecmp(v->name, "dumphistory")) { 18251 dumphistory = ast_true(v->value); 18252 } else if (!strcasecmp(v->name, "recordhistory")) { 18253 recordhistory = ast_true(v->value); 18254 } else if (!strcasecmp(v->name, "registertimeout")) { 18255 global_reg_timeout = atoi(v->value); 18256 if (global_reg_timeout < 1) 18257 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 18258 } else if (!strcasecmp(v->name, "registerattempts")) { 18259 global_regattempts_max = atoi(v->value); 18260 } else if (!strcasecmp(v->name, "bindaddr")) { 18261 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 18262 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 18263 } else { 18264 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 18265 } 18266 } else if (!strcasecmp(v->name, "localnet")) { 18267 struct ast_ha *na; 18268 if (!(na = ast_append_ha("d", v->value, localaddr))) 18269 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 18270 else 18271 localaddr = na; 18272 } else if (!strcasecmp(v->name, "localmask")) { 18273 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 18274 } else if (!strcasecmp(v->name, "externip")) { 18275 if (!(hp = ast_gethostbyname(v->value, &ahp))) 18276 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 18277 else 18278 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 18279 externexpire = 0; 18280 } else if (!strcasecmp(v->name, "externhost")) { 18281 ast_copy_string(externhost, v->value, sizeof(externhost)); 18282 if (!(hp = ast_gethostbyname(externhost, &ahp))) 18283 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 18284 else 18285 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 18286 externexpire = time(NULL); 18287 } else if (!strcasecmp(v->name, "externrefresh")) { 18288 if (sscanf(v->value, "%30d", &externrefresh) != 1) { 18289 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 18290 externrefresh = 10; 18291 } 18292 } else if (!strcasecmp(v->name, "allow")) { 18293 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1); 18294 } else if (!strcasecmp(v->name, "disallow")) { 18295 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0); 18296 } else if (!strcasecmp(v->name, "autoframing")) { 18297 global_autoframing = ast_true(v->value); 18298 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 18299 allow_external_domains = ast_true(v->value); 18300 } else if (!strcasecmp(v->name, "autodomain")) { 18301 auto_sip_domains = ast_true(v->value); 18302 } else if (!strcasecmp(v->name, "domain")) { 18303 char *domain = ast_strdupa(v->value); 18304 char *context = strchr(domain, ','); 18305 18306 if (context) 18307 *context++ = '\0'; 18308 18309 if (option_debug && ast_strlen_zero(context)) 18310 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 18311 if (ast_strlen_zero(domain)) 18312 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 18313 else 18314 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 18315 } else if (!strcasecmp(v->name, "register")) { 18316 if (sip_register(v->value, v->lineno) == 0) 18317 registry_count++; 18318 } else if (!strcasecmp(v->name, "tos")) { 18319 if (!ast_str2tos(v->value, &temp_tos)) { 18320 global_tos_sip = temp_tos; 18321 global_tos_audio = temp_tos; 18322 global_tos_video = temp_tos; 18323 ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno); 18324 } else 18325 ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno); 18326 } else if (!strcasecmp(v->name, "tos_sip")) { 18327 if (ast_str2tos(v->value, &global_tos_sip)) 18328 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); 18329 } else if (!strcasecmp(v->name, "tos_audio")) { 18330 if (ast_str2tos(v->value, &global_tos_audio)) 18331 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); 18332 } else if (!strcasecmp(v->name, "tos_video")) { 18333 if (ast_str2tos(v->value, &global_tos_video)) 18334 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); 18335 } else if (!strcasecmp(v->name, "bindport")) { 18336 if (sscanf(v->value, "%5d", &ourport) == 1) { 18337 bindaddr.sin_port = htons(ourport); 18338 } else { 18339 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 18340 } 18341 } else if (!strcasecmp(v->name, "qualify")) { 18342 if (!strcasecmp(v->value, "no")) { 18343 default_qualify = 0; 18344 } else if (!strcasecmp(v->value, "yes")) { 18345 default_qualify = DEFAULT_MAXMS; 18346 } else if (sscanf(v->value, "%30d", &default_qualify) != 1) { 18347 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 18348 default_qualify = 0; 18349 } 18350 } else if (!strcasecmp(v->name, "callevents")) { 18351 global_callevents = ast_true(v->value); 18352 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 18353 default_maxcallbitrate = atoi(v->value); 18354 if (default_maxcallbitrate < 0) 18355 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 18356 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 18357 global_matchexterniplocally = ast_true(v->value); 18358 } 18359 } 18360 18361 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 18362 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 18363 allow_external_domains = 1; 18364 } 18365 18366 /* Build list of authentication to various SIP realms, i.e. service providers */ 18367 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 18368 /* Format for authentication is auth = username:password@realm */ 18369 if (!strcasecmp(v->name, "auth")) 18370 authl = add_realm_authentication(authl, v->value, v->lineno); 18371 } 18372 18373 ucfg = ast_config_load("users.conf"); 18374 if (ucfg) { 18375 struct ast_variable *gen; 18376 int genhassip, genregistersip; 18377 const char *hassip, *registersip; 18378 18379 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 18380 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 18381 gen = ast_variable_browse(ucfg, "general"); 18382 cat = ast_category_browse(ucfg, NULL); 18383 while (cat) { 18384 if (strcasecmp(cat, "general")) { 18385 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 18386 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 18387 if (ast_true(hassip) || (!hassip && genhassip)) { 18388 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 18389 if (user) { 18390 ASTOBJ_CONTAINER_LINK(&userl,user); 18391 ASTOBJ_UNREF(user, sip_destroy_user); 18392 user_count++; 18393 } 18394 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 18395 if (peer) { 18396 ast_device_state_changed("SIP/%s", peer->name); 18397 ASTOBJ_CONTAINER_LINK(&peerl,peer); 18398 ASTOBJ_UNREF(peer, sip_destroy_peer); 18399 peer_count++; 18400 } 18401 } 18402 if (ast_true(registersip) || (!registersip && genregistersip)) { 18403 char tmp[256]; 18404 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 18405 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 18406 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 18407 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 18408 if (!host) 18409 host = ast_variable_retrieve(ucfg, "general", "host"); 18410 if (!username) 18411 username = ast_variable_retrieve(ucfg, "general", "username"); 18412 if (!secret) 18413 secret = ast_variable_retrieve(ucfg, "general", "secret"); 18414 if (!contact) 18415 contact = "s"; 18416 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 18417 if (!ast_strlen_zero(secret)) 18418 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 18419 else 18420 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 18421 if (sip_register(tmp, 0) == 0) 18422 registry_count++; 18423 } 18424 } 18425 } 18426 cat = ast_category_browse(ucfg, cat); 18427 } 18428 ast_config_destroy(ucfg); 18429 } 18430 18431 18432 /* Load peers, users and friends */ 18433 cat = NULL; 18434 while ( (cat = ast_category_browse(cfg, cat)) ) { 18435 const char *utype; 18436 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 18437 continue; 18438 utype = ast_variable_retrieve(cfg, cat, "type"); 18439 if (!utype) { 18440 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 18441 continue; 18442 } else { 18443 int is_user = 0, is_peer = 0; 18444 if (!strcasecmp(utype, "user")) 18445 is_user = 1; 18446 else if (!strcasecmp(utype, "friend")) 18447 is_user = is_peer = 1; 18448 else if (!strcasecmp(utype, "peer")) 18449 is_peer = 1; 18450 else { 18451 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 18452 continue; 18453 } 18454 if (is_user) { 18455 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 18456 if (user) { 18457 ASTOBJ_CONTAINER_LINK(&userl,user); 18458 ASTOBJ_UNREF(user, sip_destroy_user); 18459 user_count++; 18460 } 18461 } 18462 if (is_peer) { 18463 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 18464 if (peer) { 18465 ASTOBJ_CONTAINER_LINK(&peerl,peer); 18466 ASTOBJ_UNREF(peer, sip_destroy_peer); 18467 peer_count++; 18468 } 18469 } 18470 } 18471 } 18472 if (ast_find_ourip(&__ourip, bindaddr)) { 18473 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 18474 ast_config_destroy(cfg); 18475 return 0; 18476 } 18477 if (!ntohs(bindaddr.sin_port)) 18478 bindaddr.sin_port = ntohs(STANDARD_SIP_PORT); 18479 bindaddr.sin_family = AF_INET; 18480 ast_mutex_lock(&netlock); 18481 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 18482 close(sipsock); 18483 sipsock = -1; 18484 } 18485 if (sipsock < 0) { 18486 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 18487 if (sipsock < 0) { 18488 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 18489 ast_config_destroy(cfg); 18490 return -1; 18491 } else { 18492 /* Allow SIP clients on the same host to access us: */ 18493 const int reuseFlag = 1; 18494 18495 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 18496 (const char*)&reuseFlag, 18497 sizeof reuseFlag); 18498 18499 ast_enable_packet_fragmentation(sipsock); 18500 18501 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 18502 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 18503 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 18504 strerror(errno)); 18505 close(sipsock); 18506 sipsock = -1; 18507 } else { 18508 if (option_verbose > 1) { 18509 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 18510 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 18511 ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip)); 18512 } 18513 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 18514 ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip)); 18515 } 18516 } 18517 } 18518 ast_mutex_unlock(&netlock); 18519 18520 /* Add default domains - host name, IP address and IP:port */ 18521 /* Only do this if user added any sip domain with "localdomains" */ 18522 /* In order to *not* break backwards compatibility */ 18523 /* Some phones address us at IP only, some with additional port number */ 18524 if (auto_sip_domains) { 18525 char temp[MAXHOSTNAMELEN]; 18526 18527 /* First our default IP address */ 18528 if (bindaddr.sin_addr.s_addr) 18529 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 18530 else 18531 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 18532 18533 /* Our extern IP address, if configured */ 18534 if (externip.sin_addr.s_addr) 18535 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 18536 18537 /* Extern host name (NAT traversal support) */ 18538 if (!ast_strlen_zero(externhost)) 18539 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 18540 18541 /* Our host name */ 18542 if (!gethostname(temp, sizeof(temp))) 18543 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 18544 } 18545 18546 /* Release configuration from memory */ 18547 ast_config_destroy(cfg); 18548 18549 /* Load the list of manual NOTIFY types to support */ 18550 if (notify_types) 18551 ast_config_destroy(notify_types); 18552 notify_types = ast_config_load(notify_config); 18553 18554 /* Done, tell the manager */ 18555 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); 18556 18557 return 0; 18558 }
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 12017 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().
12018 { 12019 char tmp[512]; 12020 char *c; 12021 char oldnonce[256]; 12022 12023 /* table of recognised keywords, and places where they should be copied */ 12024 const struct x { 12025 const char *key; 12026 int field_index; 12027 } *i, keys[] = { 12028 { "realm=", ast_string_field_index(p, realm) }, 12029 { "nonce=", ast_string_field_index(p, nonce) }, 12030 { "opaque=", ast_string_field_index(p, opaque) }, 12031 { "qop=", ast_string_field_index(p, qop) }, 12032 { "domain=", ast_string_field_index(p, domain) }, 12033 { NULL, 0 }, 12034 }; 12035 12036 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 12037 if (ast_strlen_zero(tmp)) 12038 return -1; 12039 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 12040 ast_log(LOG_WARNING, "missing Digest.\n"); 12041 return -1; 12042 } 12043 c = tmp + strlen("Digest "); 12044 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 12045 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 12046 for (i = keys; i->key != NULL; i++) { 12047 char *src, *separator; 12048 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 12049 continue; 12050 /* Found. Skip keyword, take text in quotes or up to the separator. */ 12051 c += strlen(i->key); 12052 if (*c == '"') { 12053 src = ++c; 12054 separator = "\""; 12055 } else { 12056 src = c; 12057 separator = ","; 12058 } 12059 strsep(&c, separator); /* clear separator and move ptr */ 12060 ast_string_field_index_set(p, i->field_index, src); 12061 break; 12062 } 12063 if (i->key == NULL) /* not found, try ',' */ 12064 strsep(&c, ","); 12065 } 12066 /* Reset nonce count */ 12067 if (strcmp(p->nonce, oldnonce)) 12068 p->noncecount = 0; 12069 12070 /* Save auth data for following registrations */ 12071 if (p->registry) { 12072 struct sip_registry *r = p->registry; 12073 12074 if (strcmp(r->nonce, p->nonce)) { 12075 ast_string_field_set(r, realm, p->realm); 12076 ast_string_field_set(r, nonce, p->nonce); 12077 ast_string_field_set(r, domain, p->domain); 12078 ast_string_field_set(r, opaque, p->opaque); 12079 ast_string_field_set(r, qop, p->qop); 12080 r->noncecount = 0; 12081 } 12082 } 12083 return build_reply_digest(p, sipmethod, digest, digest_len); 12084 }
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 6254 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.
06255 { 06256 struct sip_request *orig = &p->initreq; 06257 char stripped[80]; 06258 char tmp[80]; 06259 char newto[256]; 06260 const char *c; 06261 const char *ot, *of; 06262 int is_strict = FALSE; /*!< Strict routing flag */ 06263 06264 memset(req, 0, sizeof(struct sip_request)); 06265 06266 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 06267 06268 if (!seqno) { 06269 p->ocseq++; 06270 seqno = p->ocseq; 06271 } 06272 06273 if (sipmethod == SIP_CANCEL) { 06274 p->branch = p->invite_branch; 06275 build_via(p); 06276 } else if (newbranch) { 06277 p->branch ^= ast_random(); 06278 build_via(p); 06279 } 06280 06281 /* Check for strict or loose router */ 06282 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) { 06283 is_strict = TRUE; 06284 if (sipdebug) 06285 ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid); 06286 } 06287 06288 if (sipmethod == SIP_CANCEL) 06289 c = p->initreq.rlPart2; /* Use original URI */ 06290 else if (sipmethod == SIP_ACK) { 06291 /* Use URI from Contact: in 200 OK (if INVITE) 06292 (we only have the contacturi on INVITEs) */ 06293 if (!ast_strlen_zero(p->okcontacturi)) 06294 c = is_strict ? p->route->hop : p->okcontacturi; 06295 else 06296 c = p->initreq.rlPart2; 06297 } else if (!ast_strlen_zero(p->okcontacturi)) 06298 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 06299 else if (!ast_strlen_zero(p->uri)) 06300 c = p->uri; 06301 else { 06302 char *n; 06303 /* We have no URI, use To: or From: header as URI (depending on direction) */ 06304 ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"), 06305 sizeof(stripped)); 06306 n = get_in_brackets(stripped); 06307 c = strsep(&n, ";"); /* trim ; and beyond */ 06308 } 06309 init_req(req, sipmethod, c); 06310 06311 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 06312 06313 add_header(req, "Via", p->via); 06314 if (p->route) { 06315 set_destination(p, p->route->hop); 06316 add_route(req, is_strict ? p->route->next : p->route); 06317 } 06318 06319 ot = get_header(orig, "To"); 06320 of = get_header(orig, "From"); 06321 06322 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 06323 as our original request, including tag (or presumably lack thereof) */ 06324 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 06325 /* Add the proper tag if we don't have it already. If they have specified 06326 their tag, use it. Otherwise, use our own tag */ 06327 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 06328 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06329 else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06330 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06331 else 06332 snprintf(newto, sizeof(newto), "%s", ot); 06333 ot = newto; 06334 } 06335 06336 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06337 add_header(req, "From", of); 06338 add_header(req, "To", ot); 06339 } else { 06340 add_header(req, "From", ot); 06341 add_header(req, "To", of); 06342 } 06343 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 06344 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 06345 add_header(req, "Contact", p->our_contact); 06346 06347 copy_header(req, orig, "Call-ID"); 06348 add_header(req, "CSeq", tmp); 06349 06350 if (!ast_strlen_zero(global_useragent)) 06351 add_header(req, "User-Agent", global_useragent); 06352 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 06353 06354 if (!ast_strlen_zero(p->rpid)) 06355 add_header(req, "Remote-Party-ID", p->rpid); 06356 06357 return 0; 06358 }
static int resp_needs_contact | ( | const char * | msg, | |
enum sipmethod | method | |||
) | [inline, static] |
Test if this response needs a contact header.
Definition at line 6145 of file chan_sip.c.
References SIP_ACK, SIP_BYE, SIP_CANCEL, SIP_INFO, SIP_INVITE, SIP_MESSAGE, SIP_NOTIFY, SIP_OPTIONS, SIP_PING, SIP_PRACK, SIP_PUBLISH, SIP_REFER, SIP_REGISTER, SIP_SUBSCRIBE, and SIP_UPDATE.
Referenced by respprep().
06145 { 06146 /* Requirements for Contact header inclusion in responses generated 06147 * from the header tables found in the following RFCs. Where the 06148 * Contact header was marked mandatory (m) or optional (o) this 06149 * function returns 1. 06150 * 06151 * - RFC 3261 (ACK, BYE, CANCEL, INVITE, OPTIONS, REGISTER) 06152 * - RFC 2976 (INFO) 06153 * - RFC 3262 (PRACK) 06154 * - RFC 3265 (SUBSCRIBE, NOTIFY) 06155 * - RFC 3311 (UPDATE) 06156 * - RFC 3428 (MESSAGE) 06157 * - RFC 3515 (REFER) 06158 * - RFC 3903 (PUBLISH) 06159 */ 06160 06161 switch (method) { 06162 /* 1xx, 2xx, 3xx, 485 */ 06163 case SIP_INVITE: 06164 case SIP_UPDATE: 06165 case SIP_SUBSCRIBE: 06166 case SIP_NOTIFY: 06167 if ((msg[0] >= '1' && msg[0] <= '3') || !strncmp(msg, "485", 3)) 06168 return 1; 06169 break; 06170 06171 /* 2xx, 3xx, 485 */ 06172 case SIP_REGISTER: 06173 case SIP_OPTIONS: 06174 if (msg[0] == '2' || msg[0] == '3' || !strncmp(msg, "485", 3)) 06175 return 1; 06176 break; 06177 06178 /* 3xx, 485 */ 06179 case SIP_BYE: 06180 case SIP_PRACK: 06181 case SIP_MESSAGE: 06182 case SIP_PUBLISH: 06183 if (msg[0] == '3' || !strncmp(msg, "485", 3)) 06184 return 1; 06185 break; 06186 06187 /* 2xx, 3xx, 4xx, 5xx, 6xx */ 06188 case SIP_REFER: 06189 if (msg[0] >= '2' && msg[0] <= '6') 06190 return 1; 06191 break; 06192 06193 /* contact will not be included for everything else */ 06194 case SIP_ACK: 06195 case SIP_CANCEL: 06196 case SIP_INFO: 06197 case SIP_PING: 06198 default: 06199 return 0; 06200 } 06201 return 0; 06202 }
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 6206 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, resp_needs_contact(), SIP_OUTGOING, SIP_REGISTER, SIP_SUBSCRIBE, SIPBUFSIZE, SUPPORTED_EXTENSIONS, sip_pvt::tag, and sip_pvt::theirtag.
06207 { 06208 char newto[256]; 06209 const char *ot; 06210 06211 init_resp(resp, msg); 06212 copy_via_headers(p, resp, req, "Via"); 06213 if (msg[0] == '1' || msg[0] == '2') 06214 copy_all_header(resp, req, "Record-Route"); 06215 copy_header(resp, req, "From"); 06216 ot = get_header(req, "To"); 06217 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 06218 /* Add the proper tag if we don't have it already. If they have specified 06219 their tag, use it. Otherwise, use our own tag */ 06220 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06221 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06222 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06223 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06224 else 06225 ast_copy_string(newto, ot, sizeof(newto)); 06226 ot = newto; 06227 } 06228 add_header(resp, "To", ot); 06229 copy_header(resp, req, "Call-ID"); 06230 copy_header(resp, req, "CSeq"); 06231 if (!ast_strlen_zero(global_useragent)) 06232 add_header(resp, "User-Agent", global_useragent); 06233 add_header(resp, "Allow", ALLOWED_METHODS); 06234 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 06235 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 06236 /* For registration responses, we also need expiry and 06237 contact info */ 06238 char tmp[256]; 06239 06240 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 06241 add_header(resp, "Expires", tmp); 06242 if (p->expiry) { /* Only add contact if we have an expiry time */ 06243 char contact[SIPBUFSIZE]; 06244 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 06245 add_header(resp, "Contact", contact); /* Not when we unregister */ 06246 } 06247 } else if (!ast_strlen_zero(p->our_contact) && resp_needs_contact(msg, p->method)) { 06248 add_header(resp, "Contact", p->our_contact); 06249 } 06250 return 0; 06251 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 16815 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.
16816 { 16817 /* If we're supposed to be stopped -- stay stopped */ 16818 if (monitor_thread == AST_PTHREADT_STOP) 16819 return 0; 16820 ast_mutex_lock(&monlock); 16821 if (monitor_thread == pthread_self()) { 16822 ast_mutex_unlock(&monlock); 16823 ast_log(LOG_WARNING, "Cannot kill myself\n"); 16824 return -1; 16825 } 16826 if (monitor_thread != AST_PTHREADT_NULL) { 16827 /* Wake up the thread */ 16828 pthread_kill(monitor_thread, SIGURG); 16829 } else { 16830 /* Start a new monitor */ 16831 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 16832 ast_mutex_unlock(&monlock); 16833 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 16834 return -1; 16835 } 16836 } 16837 ast_mutex_unlock(&monlock); 16838 return 0; 16839 }
static int retrans_pkt | ( | const void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 1927 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.
01928 { 01929 struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL; 01930 int reschedule = DEFAULT_RETRANS; 01931 int xmitres = 0; 01932 01933 /* Lock channel PVT */ 01934 ast_mutex_lock(&pkt->owner->lock); 01935 01936 if (pkt->retrans < MAX_RETRANS) { 01937 pkt->retrans++; 01938 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 01939 if (sipdebug && option_debug > 3) 01940 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); 01941 } else { 01942 int siptimer_a; 01943 01944 if (sipdebug && option_debug > 3) 01945 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 01946 if (!pkt->timer_a) 01947 pkt->timer_a = 2 ; 01948 else 01949 pkt->timer_a = 2 * pkt->timer_a; 01950 01951 /* For non-invites, a maximum of 4 secs */ 01952 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 01953 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 01954 siptimer_a = 4000; 01955 01956 /* Reschedule re-transmit */ 01957 reschedule = siptimer_a; 01958 if (option_debug > 3) 01959 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); 01960 } 01961 01962 if (sip_debug_test_pvt(pkt->owner)) { 01963 const struct sockaddr_in *dst = sip_real_dst(pkt->owner); 01964 ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n", 01965 pkt->retrans, sip_nat_mode(pkt->owner), 01966 ast_inet_ntoa(dst->sin_addr), 01967 ntohs(dst->sin_port), pkt->data); 01968 } 01969 01970 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data); 01971 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 01972 ast_mutex_unlock(&pkt->owner->lock); 01973 if (xmitres == XMIT_ERROR) 01974 ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid); 01975 else 01976 return reschedule; 01977 } 01978 /* Too many retries */ 01979 if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) { 01980 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 01981 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); 01982 } else if ((pkt->method == SIP_OPTIONS) && sipdebug) { 01983 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) -- See doc/sip-retransmit.txt.\n", pkt->owner->callid); 01984 } 01985 if (xmitres == XMIT_ERROR) { 01986 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission of transaction in call id %s \n", pkt->owner->callid); 01987 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01988 } else 01989 append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01990 01991 pkt->retransid = -1; 01992 01993 if (ast_test_flag(pkt, FLAG_FATAL)) { 01994 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 01995 DEADLOCK_AVOIDANCE(&pkt->owner->lock); /* SIP_PVT, not channel */ 01996 } 01997 01998 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 01999 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 02000 02001 if (pkt->owner->owner) { 02002 sip_alreadygone(pkt->owner); 02003 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); 02004 ast_queue_hangup(pkt->owner->owner); 02005 ast_channel_unlock(pkt->owner->owner); 02006 } else { 02007 /* If no channel owner, destroy now */ 02008 02009 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 02010 if (pkt->method != SIP_OPTIONS) { 02011 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 02012 sip_alreadygone(pkt->owner); 02013 if (option_debug) 02014 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 02015 } 02016 } 02017 } 02018 02019 if (pkt->method == SIP_BYE) { 02020 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 02021 if (pkt->owner->owner) 02022 ast_channel_unlock(pkt->owner->owner); 02023 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 02024 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 02025 } 02026 02027 /* In any case, go ahead and remove the packet */ 02028 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 02029 if (cur == pkt) 02030 break; 02031 } 02032 if (cur) { 02033 if (prev) 02034 prev->next = cur->next; 02035 else 02036 pkt->owner->packets = cur->next; 02037 ast_mutex_unlock(&pkt->owner->lock); 02038 free(cur); 02039 pkt = NULL; 02040 } else 02041 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 02042 if (pkt) 02043 ast_mutex_unlock(&pkt->owner->lock); 02044 return 0; 02045 }
static int scheduler_process_request_queue | ( | const void * | data | ) | [static] |
Definition at line 16380 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().
16381 { 16382 struct sip_pvt *p = (struct sip_pvt *) data; 16383 int recount = 0; 16384 int nounlock = 0; 16385 int lockretry; 16386 16387 for (lockretry = 10; lockretry > 0; lockretry--) { 16388 ast_mutex_lock(&p->lock); 16389 16390 /* lock the owner if it has one -- we may need it */ 16391 /* because this is deadlock-prone, we need to try and unlock if failed */ 16392 if (!p->owner || !ast_channel_trylock(p->owner)) { 16393 break; /* locking succeeded */ 16394 } 16395 16396 if (lockretry != 1) { 16397 ast_mutex_unlock(&p->lock); 16398 /* Sleep for a very short amount of time */ 16399 usleep(1); 16400 } 16401 } 16402 16403 if (!lockretry) { 16404 int retry = !AST_LIST_EMPTY(&p->request_queue); 16405 16406 /* we couldn't get the owner lock, which is needed to process 16407 the queued requests, so return a non-zero value, which will 16408 cause the scheduler to run this request again later if there 16409 still requests to be processed 16410 */ 16411 ast_mutex_unlock(&p->lock); 16412 return retry; 16413 }; 16414 16415 process_request_queue(p, &recount, &nounlock); 16416 p->request_queue_sched_id = -1; 16417 16418 if (p->owner && !nounlock) { 16419 ast_channel_unlock(p->owner); 16420 } 16421 ast_mutex_unlock(&p->lock); 16422 16423 if (recount) { 16424 ast_update_use_count(); 16425 } 16426 16427 return 0; 16428 }
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 2333 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.
02334 { 02335 int res; 02336 02337 add_blank(req); 02338 if (sip_debug_test_pvt(p)) { 02339 if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)) 02340 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); 02341 else 02342 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); 02343 } 02344 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02345 struct sip_request tmp; 02346 parse_copy(&tmp, req); 02347 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 02348 } 02349 res = (reliable) ? 02350 __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02351 __sip_xmit(p, req->data, req->len); 02352 return res; 02353 }
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 2305 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.
02306 { 02307 int res; 02308 02309 add_blank(req); 02310 if (sip_debug_test_pvt(p)) { 02311 const struct sockaddr_in *dst = sip_real_dst(p); 02312 02313 ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n", 02314 reliable ? "Reliably " : "", sip_nat_mode(p), 02315 ast_inet_ntoa(dst->sin_addr), 02316 ntohs(dst->sin_port), req->data); 02317 } 02318 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02319 struct sip_request tmp; 02320 parse_copy(&tmp, req); 02321 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 02322 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text); 02323 } 02324 res = (reliable) ? 02325 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02326 __sip_xmit(p, req->data, req->len); 02327 if (res > 0) 02328 return 0; 02329 return res; 02330 }
static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 8428 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().
08429 { 08430 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 08431 /* NAT: Don't trust the contact field. Just use what they came to us 08432 with. */ 08433 pvt->sa = pvt->recv; 08434 return 0; 08435 } 08436 08437 return __set_address_from_contact(pvt->fullcontact, &pvt->sa); 08438 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
Set destination from SIP URI.
Definition at line 6055 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().
06056 { 06057 char *h, *maddr, hostname[256]; 06058 int port, hn; 06059 struct hostent *hp; 06060 struct ast_hostent ahp; 06061 int debug=sip_debug_test_pvt(p); 06062 06063 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 06064 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 06065 06066 if (debug) 06067 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 06068 06069 /* Find and parse hostname */ 06070 h = strchr(uri, '@'); 06071 if (h) 06072 ++h; 06073 else { 06074 h = uri; 06075 if (strncasecmp(h, "sip:", 4) == 0) 06076 h += 4; 06077 else if (strncasecmp(h, "sips:", 5) == 0) 06078 h += 5; 06079 } 06080 hn = strcspn(h, ":;>") + 1; 06081 if (hn > sizeof(hostname)) 06082 hn = sizeof(hostname); 06083 ast_copy_string(hostname, h, hn); 06084 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 06085 h += hn - 1; 06086 06087 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 06088 if (*h == ':') { 06089 /* Parse port */ 06090 ++h; 06091 port = strtol(h, &h, 10); 06092 } 06093 else 06094 port = STANDARD_SIP_PORT; 06095 06096 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 06097 maddr = strstr(h, "maddr="); 06098 if (maddr) { 06099 maddr += 6; 06100 hn = strspn(maddr, "0123456789.") + 1; 06101 if (hn > sizeof(hostname)) 06102 hn = sizeof(hostname); 06103 ast_copy_string(hostname, maddr, hn); 06104 } 06105 06106 hp = ast_gethostbyname(hostname, &ahp); 06107 if (hp == NULL) { 06108 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 06109 return; 06110 } 06111 p->sa.sin_family = AF_INET; 06112 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 06113 p->sa.sin_port = htons(port); 06114 if (debug) 06115 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 06116 }
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 17152 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().
17153 { 17154 static int dep_insecure_very = 0; 17155 static int dep_insecure_yes = 0; 17156 17157 if (ast_strlen_zero(value)) 17158 return; 17159 17160 if (!strcasecmp(value, "very")) { 17161 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 17162 if(!dep_insecure_very) { 17163 if(lineno != -1) 17164 ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno); 17165 else 17166 ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n"); 17167 dep_insecure_very = 1; 17168 } 17169 } 17170 else if (ast_true(value)) { 17171 ast_set_flag(flags, SIP_INSECURE_PORT); 17172 if(!dep_insecure_yes) { 17173 if(lineno != -1) 17174 ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno); 17175 else 17176 ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value); 17177 dep_insecure_yes = 1; 17178 } 17179 } 17180 else if (!ast_false(value)) { 17181 char buf[64]; 17182 char *word, *next; 17183 ast_copy_string(buf, value, sizeof(buf)); 17184 next = buf; 17185 while ((word = strsep(&next, ","))) { 17186 if (!strcasecmp(word, "port")) 17187 ast_set_flag(flags, SIP_INSECURE_PORT); 17188 else if (!strcasecmp(word, "invite")) 17189 ast_set_flag(flags, SIP_INSECURE_INVITE); 17190 else 17191 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 17192 } 17193 } 17194 }
static void set_nonce_randdata | ( | struct sip_pvt * | p, | |
int | forceupdate | |||
) | [static] |
builds the sip_pvt's randdata field which is used for the nonce challenge. When forceupdate is not set, the nonce is only updated if the current one is stale. In this case, a stalenonce is one which has already received a response, if a nonce has not received a response it is not always necessary or beneficial to create a new one.
Definition at line 8746 of file chan_sip.c.
References ast_random(), ast_string_field_build, ast_strlen_zero(), sip_pvt::randdata, and sip_pvt::stalenonce.
Referenced by check_auth(), and transmit_fake_auth_response().
08747 { 08748 if (p->stalenonce || forceupdate || ast_strlen_zero(p->randdata)) { 08749 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08750 p->stalenonce = 0; 08751 } 08752 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 17583 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().
17584 { 17585 if (peer->expire == 0) { 17586 /* Don't reset expire or port time during reload 17587 if we have an active registration 17588 */ 17589 peer->expire = -1; 17590 peer->pokeexpire = -1; 17591 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 17592 } 17593 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 17594 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 17595 strcpy(peer->context, default_context); 17596 strcpy(peer->subscribecontext, default_subscribecontext); 17597 strcpy(peer->language, default_language); 17598 strcpy(peer->mohinterpret, default_mohinterpret); 17599 strcpy(peer->mohsuggest, default_mohsuggest); 17600 peer->addr.sin_family = AF_INET; 17601 peer->defaddr.sin_family = AF_INET; 17602 peer->capability = global_capability; 17603 peer->maxcallbitrate = default_maxcallbitrate; 17604 peer->rtptimeout = global_rtptimeout; 17605 peer->rtpholdtimeout = global_rtpholdtimeout; 17606 peer->rtpkeepalive = global_rtpkeepalive; 17607 peer->allowtransfer = global_allowtransfer; 17608 peer->autoframing = global_autoframing; 17609 strcpy(peer->vmexten, default_vmexten); 17610 peer->secret[0] = '\0'; 17611 peer->md5secret[0] = '\0'; 17612 peer->cid_num[0] = '\0'; 17613 peer->cid_name[0] = '\0'; 17614 peer->fromdomain[0] = '\0'; 17615 peer->fromuser[0] = '\0'; 17616 peer->regexten[0] = '\0'; 17617 peer->mailbox[0] = '\0'; 17618 peer->callgroup = 0; 17619 peer->pickupgroup = 0; 17620 peer->maxms = default_qualify; 17621 peer->prefs = default_prefs; 17622 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 18894 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().
18895 { 18896 int no = 0; 18897 int ok = FALSE; 18898 char varbuf[30]; 18899 char *inbuf = (char *) data; 18900 18901 if (ast_strlen_zero(inbuf)) { 18902 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 18903 return 0; 18904 } 18905 ast_channel_lock(chan); 18906 18907 /* Check for headers */ 18908 while (!ok && no <= 50) { 18909 no++; 18910 snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no); 18911 18912 /* Compare without the leading underscores */ 18913 if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL) ) 18914 ok = TRUE; 18915 } 18916 if (ok) { 18917 pbx_builtin_setvar_helper (chan, varbuf, inbuf); 18918 if (sipdebug) 18919 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf); 18920 } else { 18921 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 18922 } 18923 ast_channel_unlock(chan); 18924 return 0; 18925 }
static int sip_addrcmp | ( | char * | name, | |
struct sockaddr_in * | sin | |||
) | [static] |
Support routine for find_peer.
Definition at line 2709 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, inaddrcmp(), and SIP_INSECURE_PORT.
Referenced by find_peer().
02710 { 02711 /* We know name is the first field, so we can cast */ 02712 struct sip_peer *p = (struct sip_peer *) name; 02713 return !(!inaddrcmp(&p->addr, sin) || 02714 (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) && 02715 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 02716 }
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 4592 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_destroy(), 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_free_memory, ast_string_field_init, ast_string_field_set, ast_test_flag, ast_udptl_destroy(), 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().
04594 { 04595 struct sip_pvt *p; 04596 04597 if (!(p = ast_calloc(1, sizeof(*p)))) 04598 return NULL; 04599 04600 if (ast_string_field_init(p, 512)) { 04601 free(p); 04602 return NULL; 04603 } 04604 04605 ast_mutex_init(&p->lock); 04606 04607 p->method = intended_method; 04608 p->initid = -1; 04609 p->waitid = -1; 04610 p->autokillid = -1; 04611 p->request_queue_sched_id = -1; 04612 p->subscribed = NONE; 04613 p->stateid = -1; 04614 p->prefs = default_prefs; /* Set default codecs for this call */ 04615 04616 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 04617 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 04618 04619 if (sin) { 04620 p->sa = *sin; 04621 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 04622 p->ourip = __ourip; 04623 } else 04624 p->ourip = __ourip; 04625 04626 /* Copy global flags to this PVT at setup. */ 04627 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 04628 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 04629 04630 ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY); 04631 04632 p->branch = ast_random(); 04633 make_our_tag(p->tag, sizeof(p->tag)); 04634 p->ocseq = INITIAL_CSEQ; 04635 04636 if (sip_methods[intended_method].need_rtp) { 04637 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04638 /* If the global videosupport flag is on, we always create a RTP interface for video */ 04639 if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 04640 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04641 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) 04642 p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 04643 if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) { 04644 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", 04645 ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno)); 04646 /* If rtp was successfully allocated, but vrtp was not, then we need to be sure to free rtp here */ 04647 if (p->rtp) { 04648 ast_rtp_destroy(p->rtp); 04649 } 04650 if (p->udptl) { 04651 ast_udptl_destroy(p->udptl); 04652 } 04653 ast_mutex_destroy(&p->lock); 04654 if (p->chanvars) { 04655 ast_variables_destroy(p->chanvars); 04656 p->chanvars = NULL; 04657 } 04658 ast_string_field_free_memory(p); 04659 free(p); 04660 return NULL; 04661 } 04662 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04663 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04664 ast_rtp_settos(p->rtp, global_tos_audio); 04665 ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); 04666 ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); 04667 ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); 04668 if (p->vrtp) { 04669 ast_rtp_settos(p->vrtp, global_tos_video); 04670 ast_rtp_setdtmf(p->vrtp, 0); 04671 ast_rtp_setdtmfcompensate(p->vrtp, 0); 04672 ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); 04673 ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout); 04674 ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); 04675 } 04676 if (p->udptl) 04677 ast_udptl_settos(p->udptl, global_tos_audio); 04678 p->maxcallbitrate = default_maxcallbitrate; 04679 p->autoframing = global_autoframing; 04680 ast_rtp_codec_setpref(p->rtp, &p->prefs); 04681 } 04682 04683 if (useglobal_nat && sin) { 04684 /* Setup NAT structure according to global settings if we have an address */ 04685 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 04686 p->recv = *sin; 04687 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04688 } 04689 04690 if (p->method != SIP_REGISTER) 04691 ast_string_field_set(p, fromdomain, default_fromdomain); 04692 build_via(p); 04693 if (!callid) 04694 build_callid_pvt(p); 04695 else 04696 ast_string_field_set(p, callid, callid); 04697 /* Assign default music on hold class */ 04698 ast_string_field_set(p, mohinterpret, default_mohinterpret); 04699 ast_string_field_set(p, mohsuggest, default_mohsuggest); 04700 p->capability = global_capability; 04701 p->allowtransfer = global_allowtransfer; 04702 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 04703 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 04704 p->noncodeccapability |= AST_RTP_DTMF; 04705 if (p->udptl) { 04706 p->t38.capability = global_t38_capability; 04707 if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY) 04708 p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 04709 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC) 04710 p->t38.capability |= T38FAX_UDP_EC_FEC; 04711 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE) 04712 p->t38.capability |= T38FAX_UDP_EC_NONE; 04713 p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 04714 p->t38.jointcapability = p->t38.capability; 04715 } 04716 ast_string_field_set(p, context, default_context); 04717 04718 AST_LIST_HEAD_INIT_NOLOCK(&p->request_queue); 04719 04720 /* Add to active dialog list */ 04721 ast_mutex_lock(&iflock); 04722 p->next = iflist; 04723 iflist = p; 04724 ast_mutex_unlock(&iflock); 04725 if (option_debug) 04726 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"); 04727 return p; 04728 }
static void sip_alreadygone | ( | struct sip_pvt * | dialog | ) | [static] |
Definition at line 1678 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().
01679 { 01680 if (option_debug > 2) 01681 ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 01682 ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE); 01683 }
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 3777 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, ast_channel::tech_pvt, transmit_response_with_sdp(), try_suggested_sip_codec(), and XMIT_CRITICAL.
03778 { 03779 int res = 0; 03780 struct sip_pvt *p = ast->tech_pvt; 03781 03782 ast_mutex_lock(&p->lock); 03783 if (ast->_state != AST_STATE_UP) { 03784 try_suggested_sip_codec(p); 03785 03786 ast_setstate(ast, AST_STATE_UP); 03787 if (option_debug) 03788 ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name); 03789 03790 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03791 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 03792 } 03793 ast_mutex_unlock(&p->lock); 03794 return res; 03795 }
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 3038 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, sip_pvt::t38, 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.
03039 { 03040 int res, xmitres = 0; 03041 struct sip_pvt *p; 03042 struct varshead *headp; 03043 struct ast_var_t *current; 03044 const char *referer = NULL; /* SIP refererer */ 03045 03046 p = ast->tech_pvt; 03047 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 03048 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 03049 return -1; 03050 } 03051 03052 /* Check whether there is vxml_url, distinctive ring variables */ 03053 headp=&ast->varshead; 03054 AST_LIST_TRAVERSE(headp,current,entries) { 03055 /* Check whether there is a VXML_URL variable */ 03056 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 03057 p->options->vxml_url = ast_var_value(current); 03058 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 03059 p->options->uri_options = ast_var_value(current); 03060 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 03061 /* Check whether there is a ALERT_INFO variable */ 03062 p->options->distinctive_ring = ast_var_value(current); 03063 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 03064 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 03065 p->options->addsipheaders = 1; 03066 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 03067 /* This is a transfered call */ 03068 p->options->transfer = 1; 03069 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 03070 /* This is the referer */ 03071 referer = ast_var_value(current); 03072 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 03073 /* We're replacing a call. */ 03074 p->options->replaces = ast_var_value(current); 03075 } 03076 } 03077 03078 res = 0; 03079 ast_set_flag(&p->flags[0], SIP_OUTGOING); 03080 03081 if (p->options->transfer) { 03082 char buf[SIPBUFSIZE/2]; 03083 03084 if (referer) { 03085 if (sipdebug && option_debug > 2) 03086 ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer); 03087 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 03088 } else 03089 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 03090 ast_string_field_set(p, cid_name, buf); 03091 } 03092 if (option_debug) 03093 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 03094 03095 res = update_call_counter(p, INC_CALL_RINGING); 03096 if ( res != -1 ) { 03097 p->callingpres = ast->cid.cid_pres; 03098 p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec); 03099 p->jointnoncodeccapability = p->noncodeccapability; 03100 03101 /* If there are no audio formats left to offer, punt */ 03102 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 03103 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 03104 res = -1; 03105 } else { 03106 p->t38.jointcapability = p->t38.capability; 03107 if (option_debug > 1) 03108 ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability); 03109 xmitres = transmit_invite(p, SIP_INVITE, 1, 2); 03110 if (xmitres == XMIT_ERROR) 03111 return -1; /* Transmission error */ 03112 03113 p->invitestate = INV_CALLING; 03114 03115 /* Initialize auto-congest time */ 03116 AST_SCHED_DEL(sched, p->initid); 03117 p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p); 03118 } 03119 } else { 03120 ast->hangupcause = AST_CAUSE_USER_BUSY; 03121 } 03122 return res; 03123 }
static int sip_cancel_destroy | ( | struct sip_pvt * | p | ) | [static] |
Cancel destruction of SIP dialog.
Definition at line 2176 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().
02177 { 02178 int res = 0; 02179 if (p->autokillid > -1) { 02180 if (!(res = ast_sched_del(sched, p->autokillid))) { 02181 append_history(p, "CancelDestroy", ""); 02182 p->autokillid = -1; 02183 } 02184 } 02185 return res; 02186 }
static int sip_debug_test_addr | ( | const struct sockaddr_in * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 1760 of file chan_sip.c.
References sipdebug.
Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().
01761 { 01762 if (!sipdebug) 01763 return 0; 01764 if (debugaddr.sin_addr.s_addr) { 01765 if (((ntohs(debugaddr.sin_port) != 0) 01766 && (debugaddr.sin_port != addr->sin_port)) 01767 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01768 return 0; 01769 } 01770 return 1; 01771 }
static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 1786 of file chan_sip.c.
References sip_debug_test_addr(), sip_real_dst(), and sipdebug.
Referenced by __sip_destroy(), add_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().
01787 { 01788 if (!sipdebug) 01789 return 0; 01790 return sip_debug_test_addr(sip_real_dst(p)); 01791 }
static void sip_destroy | ( | struct sip_pvt * | p | ) | [static] |
Destroy SIP call structure.
Definition at line 3405 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().
03406 { 03407 ast_mutex_lock(&iflock); 03408 if (option_debug > 2) 03409 ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid); 03410 __sip_destroy(p, 1); 03411 ast_mutex_unlock(&iflock); 03412 }
static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 2517 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().
02518 { 02519 if (option_debug > 2) 02520 ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name); 02521 02522 /* Delete it, it needs to disappear */ 02523 if (peer->call) 02524 sip_destroy(peer->call); 02525 02526 if (peer->mwipvt) /* We have an active subscription, delete it */ 02527 sip_destroy(peer->mwipvt); 02528 02529 if (peer->chanvars) { 02530 ast_variables_destroy(peer->chanvars); 02531 peer->chanvars = NULL; 02532 } 02533 02534 register_peer_exten(peer, FALSE); 02535 ast_free_ha(peer->ha); 02536 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT)) 02537 apeerobjs--; 02538 else if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) 02539 rpeerobjs--; 02540 else 02541 speerobjs--; 02542 clear_realm_authentication(peer->auth); 02543 peer->auth = NULL; 02544 free(peer); 02545 }
static void sip_destroy_user | ( | struct sip_user * | user | ) | [static] |
Remove user object from in-memory storage.
Definition at line 2737 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().
02738 { 02739 if (option_debug > 2) 02740 ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name); 02741 ast_free_ha(user->ha); 02742 if (user->chanvars) { 02743 ast_variables_destroy(user->chanvars); 02744 user->chanvars = NULL; 02745 } 02746 if (ast_test_flag(&user->flags[0], SIP_REALTIME)) 02747 ruserobjs--; 02748 else 02749 suserobjs--; 02750 free(user); 02751 }
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 16987 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().
16988 { 16989 char *host; 16990 char *tmp; 16991 16992 struct hostent *hp; 16993 struct ast_hostent ahp; 16994 struct sip_peer *p; 16995 16996 int res = AST_DEVICE_INVALID; 16997 16998 /* make sure data is not null. Maybe unnecessary, but better be safe */ 16999 host = ast_strdupa(data ? data : ""); 17000 if ((tmp = strchr(host, '@'))) 17001 host = tmp + 1; 17002 17003 if (option_debug > 2) 17004 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 17005 17006 /* If find_peer asks for a realtime peer, then this breaks rtautoclear. This 17007 * is because when a peer tries to autoexpire, the last thing it does is to 17008 * queue up an event telling the system that the devicestate has changed 17009 * (presumably to unavailable). If we ask for a realtime peer here, this would 17010 * load it BACK into memory, thus defeating the point of trying to trying to 17011 * clear dead hosts out of memory. 17012 */ 17013 if ((p = find_peer(host, NULL, 0, 1))) { 17014 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 17015 /* we have an address for the peer */ 17016 17017 /* Check status in this order 17018 - Hold 17019 - Ringing 17020 - Busy (enforced only by call limit) 17021 - Inuse (we have a call) 17022 - Unreachable (qualify) 17023 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 17024 for registered devices */ 17025 17026 if (p->onHold) 17027 /* First check for hold or ring states */ 17028 res = AST_DEVICE_ONHOLD; 17029 else if (p->inRinging) { 17030 if (p->inRinging == p->inUse) 17031 res = AST_DEVICE_RINGING; 17032 else 17033 res = AST_DEVICE_RINGINUSE; 17034 } else if (p->call_limit && (p->inUse == p->call_limit)) 17035 /* check call limit */ 17036 res = AST_DEVICE_BUSY; 17037 else if (p->call_limit && p->inUse) 17038 /* Not busy, but we do have a call */ 17039 res = AST_DEVICE_INUSE; 17040 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 17041 /* We don't have a call. Are we reachable at all? Requires qualify= */ 17042 res = AST_DEVICE_UNAVAILABLE; 17043 else /* Default reply if we're registered and have no other data */ 17044 res = AST_DEVICE_NOT_INUSE; 17045 } else { 17046 /* there is no address, it's unavailable */ 17047 res = AST_DEVICE_UNAVAILABLE; 17048 } 17049 ASTOBJ_UNREF(p,sip_destroy_peer); 17050 } else { 17051 char *port = strchr(host, ':'); 17052 if (port) 17053 *port = '\0'; 17054 hp = ast_gethostbyname(host, &ahp); 17055 if (hp) 17056 res = AST_DEVICE_UNKNOWN; 17057 } 17058 17059 return res; 17060 }
static int sip_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 11830 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.
11831 { 11832 int oldsipdebug = sipdebug_console; 11833 if (argc != 3) { 11834 if (argc != 5) 11835 return RESULT_SHOWUSAGE; 11836 else if (strcmp(argv[3], "ip") == 0) 11837 return sip_do_debug_ip(fd, argc, argv); 11838 else if (strcmp(argv[3], "peer") == 0) 11839 return sip_do_debug_peer(fd, argc, argv); 11840 else 11841 return RESULT_SHOWUSAGE; 11842 } 11843 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11844 memset(&debugaddr, 0, sizeof(debugaddr)); 11845 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11846 return RESULT_SUCCESS; 11847 }
static int sip_do_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11849 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.
11850 { 11851 int oldsipdebug = sipdebug_console; 11852 char *newargv[6] = { "sip", "set", "debug", NULL }; 11853 if (argc != 2) { 11854 if (argc != 4) 11855 return RESULT_SHOWUSAGE; 11856 else if (strcmp(argv[2], "ip") == 0) { 11857 newargv[3] = argv[2]; 11858 newargv[4] = argv[3]; 11859 return sip_do_debug_ip(fd, argc + 1, newargv); 11860 } else if (strcmp(argv[2], "peer") == 0) { 11861 newargv[3] = argv[2]; 11862 newargv[4] = argv[3]; 11863 return sip_do_debug_peer(fd, argc + 1, newargv); 11864 } else 11865 return RESULT_SHOWUSAGE; 11866 } 11867 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11868 memset(&debugaddr, 0, sizeof(debugaddr)); 11869 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11870 return RESULT_SUCCESS; 11871 }
static int sip_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP Debugging in CLI.
Definition at line 11776 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().
11777 { 11778 struct hostent *hp; 11779 struct ast_hostent ahp; 11780 int port = 0; 11781 char *p, *arg; 11782 11783 /* sip set debug ip <ip> */ 11784 if (argc != 5) 11785 return RESULT_SHOWUSAGE; 11786 p = arg = argv[4]; 11787 strsep(&p, ":"); 11788 if (p) 11789 port = atoi(p); 11790 hp = ast_gethostbyname(arg, &ahp); 11791 if (hp == NULL) 11792 return RESULT_SHOWUSAGE; 11793 11794 debugaddr.sin_family = AF_INET; 11795 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 11796 debugaddr.sin_port = htons(port); 11797 if (port == 0) 11798 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 11799 else 11800 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 11801 11802 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11803 11804 return RESULT_SUCCESS; 11805 }
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 11808 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().
11809 { 11810 struct sip_peer *peer; 11811 if (argc != 5) 11812 return RESULT_SHOWUSAGE; 11813 peer = find_peer(argv[4], NULL, 1, 0); 11814 if (peer) { 11815 if (peer->addr.sin_addr.s_addr) { 11816 debugaddr.sin_family = AF_INET; 11817 debugaddr.sin_addr = peer->addr.sin_addr; 11818 debugaddr.sin_port = peer->addr.sin_port; 11819 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 11820 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11821 } else 11822 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]); 11823 ASTOBJ_UNREF(peer,sip_destroy_peer); 11824 } else 11825 ast_cli(fd, "No such peer '%s'\n", argv[4]); 11826 return RESULT_SUCCESS; 11827 }
static int sip_do_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP History logging (CLI).
Definition at line 11949 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and TRUE.
11950 { 11951 if (argc != 2) { 11952 return RESULT_SHOWUSAGE; 11953 } 11954 recordhistory = TRUE; 11955 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 11956 return RESULT_SUCCESS; 11957 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 19040 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().
19041 { 19042 reload_config(reason); 19043 19044 /* Prune peers who still are supposed to be deleted */ 19045 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 19046 if (option_debug > 3) 19047 ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n"); 19048 19049 /* Send qualify (OPTIONS) to all peers */ 19050 sip_poke_all_peers(); 19051 19052 /* Register with all services */ 19053 sip_send_all_registers(); 19054 19055 if (option_debug > 3) 19056 ast_log(LOG_DEBUG, "--------------- SIP reload done\n"); 19057 19058 return 0; 19059 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 18839 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().
18840 { 18841 struct sip_pvt *p; 18842 char *mode; 18843 if (data) 18844 mode = (char *)data; 18845 else { 18846 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 18847 return 0; 18848 } 18849 ast_channel_lock(chan); 18850 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 18851 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 18852 ast_channel_unlock(chan); 18853 return 0; 18854 } 18855 p = chan->tech_pvt; 18856 if (!p) { 18857 ast_channel_unlock(chan); 18858 return 0; 18859 } 18860 ast_mutex_lock(&p->lock); 18861 if (!strcasecmp(mode,"info")) { 18862 ast_clear_flag(&p->flags[0], SIP_DTMF); 18863 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 18864 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 18865 } else if (!strcasecmp(mode,"rfc2833")) { 18866 ast_clear_flag(&p->flags[0], SIP_DTMF); 18867 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 18868 p->jointnoncodeccapability |= AST_RTP_DTMF; 18869 } else if (!strcasecmp(mode,"inband")) { 18870 ast_clear_flag(&p->flags[0], SIP_DTMF); 18871 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 18872 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 18873 } else 18874 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 18875 if (p->rtp) 18876 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 18877 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 18878 if (!p->vad) { 18879 p->vad = ast_dsp_new(); 18880 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 18881 } 18882 } else { 18883 if (p->vad) { 18884 ast_dsp_free(p->vad); 18885 p->vad = NULL; 18886 } 18887 } 18888 ast_mutex_unlock(&p->lock); 18889 ast_channel_unlock(chan); 18890 return 0; 18891 }
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 11634 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().
11635 { 11636 int x = 0; 11637 struct sip_history *hist; 11638 static int errmsg = 0; 11639 11640 if (!dialog) 11641 return; 11642 11643 if (!option_debug && !sipdebug) { 11644 if (!errmsg) { 11645 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 11646 errmsg = 1; 11647 } 11648 return; 11649 } 11650 11651 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 11652 if (dialog->subscribed) 11653 ast_log(LOG_DEBUG, " * Subscription\n"); 11654 else 11655 ast_log(LOG_DEBUG, " * SIP Call\n"); 11656 if (dialog->history) 11657 AST_LIST_TRAVERSE(dialog->history, hist, list) 11658 ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); 11659 if (!x) 11660 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 11661 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 11662 }
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 3890 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.
03891 { 03892 int ret = -1; 03893 struct sip_pvt *p; 03894 03895 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug) 03896 ast_log(LOG_DEBUG, "New channel is zombie\n"); 03897 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug) 03898 ast_log(LOG_DEBUG, "Old channel is zombie\n"); 03899 03900 if (!newchan || !newchan->tech_pvt) { 03901 if (!newchan) 03902 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 03903 else 03904 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 03905 return -1; 03906 } 03907 p = newchan->tech_pvt; 03908 03909 if (!p) { 03910 ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n"); 03911 return -1; 03912 } 03913 03914 ast_mutex_lock(&p->lock); 03915 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 03916 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 03917 if (p->owner != oldchan) 03918 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 03919 else { 03920 p->owner = newchan; 03921 /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native 03922 RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be 03923 able to do this if the masquerade happens before the bridge breaks (e.g., AMI 03924 redirect of both channels). Note that a channel can not be masqueraded *into* 03925 a native bridge. So there is no danger that this breaks a native bridge that 03926 should stay up. */ 03927 sip_set_rtp_peer(newchan, NULL, NULL, 0, 0); 03928 ret = 0; 03929 } 03930 if (option_debug > 2) 03931 ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 03932 03933 ast_mutex_unlock(&p->lock); 03934 return ret; 03935 }
static int sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Return SIP UA's codec (part of the RTP interface).
Definition at line 18984 of file chan_sip.c.
References sip_pvt::capability, sip_pvt::jointcapability, and ast_channel::tech_pvt.
18985 { 18986 struct sip_pvt *p = chan->tech_pvt; 18987 return p->jointcapability ? p->jointcapability : p->capability; 18988 }
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 18695 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.
18696 { 18697 struct sip_pvt *p = NULL; 18698 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 18699 18700 if (!(p = chan->tech_pvt)) 18701 return AST_RTP_GET_FAILED; 18702 18703 ast_mutex_lock(&p->lock); 18704 if (!(p->rtp)) { 18705 ast_mutex_unlock(&p->lock); 18706 return AST_RTP_GET_FAILED; 18707 } 18708 18709 *rtp = p->rtp; 18710 18711 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 18712 res = AST_RTP_TRY_PARTIAL; 18713 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 18714 res = AST_RTP_TRY_NATIVE; 18715 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 18716 res = AST_RTP_GET_FAILED; 18717 18718 ast_mutex_unlock(&p->lock); 18719 18720 return res; 18721 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 18560 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.
18561 { 18562 struct sip_pvt *p; 18563 struct ast_udptl *udptl = NULL; 18564 18565 p = chan->tech_pvt; 18566 if (!p) 18567 return NULL; 18568 18569 ast_mutex_lock(&p->lock); 18570 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 18571 udptl = p->udptl; 18572 ast_mutex_unlock(&p->lock); 18573 return udptl; 18574 }
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 18724 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.
18725 { 18726 struct sip_pvt *p = NULL; 18727 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 18728 18729 if (!(p = chan->tech_pvt)) 18730 return AST_RTP_GET_FAILED; 18731 18732 ast_mutex_lock(&p->lock); 18733 if (!(p->vrtp)) { 18734 ast_mutex_unlock(&p->lock); 18735 return AST_RTP_GET_FAILED; 18736 } 18737 18738 *rtp = p->vrtp; 18739 18740 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 18741 res = AST_RTP_TRY_NATIVE; 18742 18743 ast_mutex_unlock(&p->lock); 18744 18745 return res; 18746 }
static int sip_handle_t38_reinvite | ( | struct ast_channel * | chan, | |
struct sip_pvt * | pvt, | |||
int | reinvite | |||
) | [static] |
Handle T38 reinvite.
Definition at line 18612 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().
18613 { 18614 struct sip_pvt *p; 18615 int flag = 0; 18616 18617 p = chan->tech_pvt; 18618 if (!p || !pvt->udptl) 18619 return -1; 18620 18621 /* Setup everything on the other side like offered/responded from first side */ 18622 ast_mutex_lock(&p->lock); 18623 18624 /*! \todo check if this is not set earlier when setting up the PVT. If not 18625 maybe it should move there. */ 18626 p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability; 18627 18628 ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 18629 ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 18630 ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl)); 18631 18632 if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */ 18633 /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects, 18634 not really T38 re-invites which are different. In this 18635 case it's used properly, to see if we can reinvite over 18636 NAT 18637 */ 18638 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 18639 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 18640 flag =1; 18641 } else { 18642 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18643 } 18644 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 18645 if (!p->pendinginvite) { 18646 if (option_debug > 2) { 18647 if (flag) 18648 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)); 18649 else 18650 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)); 18651 } 18652 transmit_reinvite_with_t38_sdp(p); 18653 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18654 if (option_debug > 2) { 18655 if (flag) 18656 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)); 18657 else 18658 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)); 18659 } 18660 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18661 } 18662 } 18663 /* Reset lastrtprx timer */ 18664 p->lastrtprx = p->lastrtptx = time(NULL); 18665 ast_mutex_unlock(&p->lock); 18666 return 0; 18667 } else { /* If we are handling sending 200 OK to the other side of the bridge */ 18668 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 18669 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 18670 flag = 1; 18671 } else { 18672 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18673 } 18674 if (option_debug > 2) { 18675 if (flag) 18676 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)); 18677 else 18678 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)); 18679 } 18680 pvt->t38.state = T38_ENABLED; 18681 p->t38.state = T38_ENABLED; 18682 if (option_debug > 1) { 18683 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 18684 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 18685 } 18686 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 18687 p->lastrtprx = p->lastrtptx = time(NULL); 18688 ast_mutex_unlock(&p->lock); 18689 return 0; 18690 } 18691 }
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 3578 of file chan_sip.c.
References __sip_semi_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, sip_pkt::data, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, FALSE, find_sip_method(), FLAG_RESPONSE, sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, sip_pvt::hangupcause, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, sip_pkt::method, sip_pkt::next, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, sched, sip_pkt::seqno, 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.
03579 { 03580 struct sip_pvt *p = ast->tech_pvt; 03581 int needcancel = FALSE; 03582 int needdestroy = 0; 03583 struct ast_channel *oldowner = ast; 03584 03585 if (!p) { 03586 if (option_debug) 03587 ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n"); 03588 return 0; 03589 } 03590 03591 /* Store hangupcause locally in PVT so we still have it before disconnect */ 03592 if (p->owner) 03593 p->hangupcause = p->owner->hangupcause; 03594 03595 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 03596 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03597 if (option_debug && sipdebug) 03598 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03599 update_call_counter(p, DEC_CALL_LIMIT); 03600 } 03601 if (option_debug >3) 03602 ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 03603 if (p->autokillid > -1 && sip_cancel_destroy(p)) 03604 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03605 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03606 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 03607 ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY); 03608 p->owner->tech_pvt = NULL; 03609 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 03610 return 0; 03611 } 03612 if (option_debug) { 03613 if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug) 03614 ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 03615 else { 03616 if (option_debug) 03617 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 03618 } 03619 } 03620 if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 03621 ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n"); 03622 03623 ast_mutex_lock(&p->lock); 03624 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03625 if (option_debug && sipdebug) 03626 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03627 update_call_counter(p, DEC_CALL_LIMIT); 03628 } 03629 03630 /* Determine how to disconnect */ 03631 if (p->owner != ast) { 03632 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 03633 ast_mutex_unlock(&p->lock); 03634 return 0; 03635 } 03636 /* If the call is not UP, we need to send CANCEL instead of BYE */ 03637 if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) { 03638 needcancel = TRUE; 03639 if (option_debug > 3) 03640 ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 03641 } 03642 03643 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 03644 03645 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->hangupcause) : "Unknown"); 03646 03647 /* Disconnect */ 03648 if (p->vad) 03649 ast_dsp_free(p->vad); 03650 03651 p->owner = NULL; 03652 ast->tech_pvt = NULL; 03653 03654 ast_module_unref(ast_module_info->self); 03655 03656 /* Do not destroy this pvt until we have timeout or 03657 get an answer to the BYE or INVITE/CANCEL 03658 If we get no answer during retransmit period, drop the call anyway. 03659 (Sorry, mother-in-law, you can't deny a hangup by sending 03660 603 declined to BYE...) 03661 */ 03662 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) 03663 needdestroy = 1; /* Set destroy flag at end of this function */ 03664 else if (p->invitestate != INV_CALLING) 03665 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03666 03667 /* Start the process if it's not already started */ 03668 if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 03669 if (needcancel) { /* Outgoing call, not up */ 03670 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03671 /* stop retransmitting an INVITE that has not received a response */ 03672 struct sip_pkt *cur; 03673 for (cur = p->packets; cur; cur = cur->next) { 03674 __sip_semi_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), cur->method ? cur->method : find_sip_method(cur->data)); 03675 } 03676 03677 /* if we can't send right now, mark it pending */ 03678 if (p->invitestate == INV_CALLING) { 03679 /* We can't send anything in CALLING state */ 03680 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03681 /* 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. */ 03682 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03683 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 03684 } else { 03685 p->invitestate = INV_CANCELLED; 03686 /* Send a new request: CANCEL */ 03687 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 03688 /* Actually don't destroy us yet, wait for the 487 on our original 03689 INVITE, but do set an autodestruct just in case we never get it. */ 03690 needdestroy = 0; 03691 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03692 } 03693 } else { /* Incoming call, not up */ 03694 const char *res; 03695 if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause))) 03696 transmit_response_reliable(p, res, &p->initreq); 03697 else 03698 transmit_response_reliable(p, "603 Declined", &p->initreq); 03699 p->invitestate = INV_TERMINATED; 03700 } 03701 } else { /* Call is in UP state, send BYE */ 03702 if (!p->pendinginvite) { 03703 char *audioqos = ""; 03704 char *videoqos = ""; 03705 if (p->rtp) 03706 audioqos = ast_rtp_get_quality(p->rtp, NULL); 03707 if (p->vrtp) 03708 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 03709 /* Send a hangup */ 03710 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03711 03712 /* Get RTCP quality before end of call */ 03713 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 03714 if (p->rtp) 03715 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 03716 if (p->vrtp) 03717 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 03718 } 03719 if (p->rtp && oldowner) 03720 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); 03721 if (p->vrtp && oldowner) 03722 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos); 03723 } else { 03724 /* Note we will need a BYE when this all settles out 03725 but we can't send one while we have "INVITE" outstanding. */ 03726 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03727 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 03728 AST_SCHED_DEL(sched, p->waitid); 03729 if (sip_cancel_destroy(p)) 03730 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03731 } 03732 } 03733 } 03734 if (needdestroy) 03735 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 03736 ast_mutex_unlock(&p->lock); 03737 return 0; 03738 }
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 4006 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.
04007 { 04008 struct sip_pvt *p = ast->tech_pvt; 04009 int res = 0; 04010 04011 ast_mutex_lock(&p->lock); 04012 switch(condition) { 04013 case AST_CONTROL_RINGING: 04014 if (ast->_state == AST_STATE_RING) { 04015 p->invitestate = INV_EARLY_MEDIA; 04016 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 04017 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 04018 /* Send 180 ringing if out-of-band seems reasonable */ 04019 transmit_response(p, "180 Ringing", &p->initreq); 04020 ast_set_flag(&p->flags[0], SIP_RINGING); 04021 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 04022 break; 04023 } else { 04024 /* Well, if it's not reasonable, just send in-band */ 04025 } 04026 } 04027 res = -1; 04028 break; 04029 case AST_CONTROL_BUSY: 04030 if (ast->_state != AST_STATE_UP) { 04031 transmit_response_reliable(p, "486 Busy Here", &p->initreq); 04032 p->invitestate = INV_COMPLETED; 04033 sip_alreadygone(p); 04034 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 04035 break; 04036 } 04037 res = -1; 04038 break; 04039 case AST_CONTROL_CONGESTION: 04040 if (ast->_state != AST_STATE_UP) { 04041 transmit_response_reliable(p, "503 Service Unavailable", &p->initreq); 04042 p->invitestate = INV_COMPLETED; 04043 sip_alreadygone(p); 04044 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 04045 break; 04046 } 04047 res = -1; 04048 break; 04049 case AST_CONTROL_PROCEEDING: 04050 if ((ast->_state != AST_STATE_UP) && 04051 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 04052 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 04053 transmit_response(p, "100 Trying", &p->initreq); 04054 p->invitestate = INV_PROCEEDING; 04055 break; 04056 } 04057 res = -1; 04058 break; 04059 case AST_CONTROL_PROGRESS: 04060 if ((ast->_state != AST_STATE_UP) && 04061 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 04062 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 04063 p->invitestate = INV_EARLY_MEDIA; 04064 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 04065 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 04066 break; 04067 } 04068 res = -1; 04069 break; 04070 case AST_CONTROL_HOLD: 04071 ast_rtp_new_source(p->rtp); 04072 ast_moh_start(ast, data, p->mohinterpret); 04073 break; 04074 case AST_CONTROL_UNHOLD: 04075 ast_rtp_new_source(p->rtp); 04076 ast_moh_stop(ast); 04077 break; 04078 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 04079 if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 04080 transmit_info_with_vidupdate(p); 04081 /* ast_rtcp_send_h261fur(p->vrtp); */ 04082 } else 04083 res = -1; 04084 break; 04085 case AST_CONTROL_SRCUPDATE: 04086 ast_rtp_new_source(p->rtp); 04087 break; 04088 case -1: 04089 res = -1; 04090 break; 04091 default: 04092 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 04093 res = -1; 04094 break; 04095 } 04096 ast_mutex_unlock(&p->lock); 04097 return res; 04098 }
static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 1780 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().
01781 { 01782 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT"; 01783 }
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 4106 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, ast_channel::hangupcause, sip_pvt::jointcapability, language, sip_pvt::language, sip_pvt::lock, LOG_DEBUG, ast_channel::name, 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_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_NO_HISTORY, sip_tech, sip_tech_info, SIPBUFSIZE, 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().
04107 { 04108 struct ast_channel *tmp; 04109 struct ast_variable *v = NULL; 04110 int fmt; 04111 int what; 04112 int needvideo = 0, video = 0; 04113 char *decoded_exten; 04114 04115 if (option_debug != 0) { 04116 ast_verbose(VERBOSE_PREFIX_3 "NEW SIP CHANNEL, title: <%s>\n", title?title:"Null"); 04117 ast_verbose(VERBOSE_PREFIX_3 "from: %s\n", i->from); 04118 ast_verbose(VERBOSE_PREFIX_3 "username: <%s>\n", i->username); 04119 ast_verbose(VERBOSE_PREFIX_3 "peername: <%s>\n", i->peername); 04120 ast_verbose(VERBOSE_PREFIX_3 "fromdomain: %s\n", i->fromdomain); 04121 ast_verbose(VERBOSE_PREFIX_3 "fromuser: %s\n", i->fromuser); 04122 ast_verbose(VERBOSE_PREFIX_3 "fromname: %s\n", i->fromname); 04123 ast_verbose(VERBOSE_PREFIX_3 "fullcontact: %s\n", i->fullcontact); 04124 } 04125 04126 { 04127 char my_name[128]; /* pick a good name */ 04128 const char *f, *fromdomain = NULL; 04129 04130 if (!ast_strlen_zero(i->fromdomain) && strchr(i->fromdomain,':')) 04131 fromdomain = strchr(i->fromdomain,':') + 1; /* skip ':' */ 04132 else 04133 fromdomain = i->fromdomain; 04134 04135 if (!ast_strlen_zero(i->username)) { 04136 if (!ast_strlen_zero(title) && strcmp(i->username, title)) { 04137 /* title not empty and different from username */ 04138 snprintf(my_name, sizeof(my_name), "%s@%s", i->username, title); 04139 } else { 04140 /* username not empty, title is empty or equal to username */ 04141 snprintf(my_name, sizeof(my_name), "%s", i->username); 04142 } 04143 } else { /* username empty */ 04144 if (!ast_strlen_zero(i->peername)) { 04145 /* call from unregisted peer */ 04146 snprintf(my_name, sizeof(my_name), "%s", i->peername); 04147 } else { /* username and peername empty */ 04148 if (!ast_strlen_zero(title)) { /* title not empty */ 04149 snprintf(my_name, sizeof(my_name), "%s", title); 04150 } else if (!ast_strlen_zero(i->from)) { /* title empty, From: not empty */ 04151 f = i->from; 04152 if (!strncmp(f, "sip:", 4)) 04153 f += 4; 04154 snprintf(my_name, sizeof(my_name), "%s", f); 04155 } else { /* fallback to fromdomain */ 04156 snprintf(my_name, sizeof(my_name), "%s", fromdomain); 04157 } 04158 } 04159 } 04160 ast_mutex_unlock(&i->lock); 04161 /* Don't hold a sip pvt lock while we allocate a channel */ 04162 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); 04163 04164 } 04165 if (!tmp) { 04166 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 04167 ast_mutex_lock(&i->lock); 04168 return NULL; 04169 } 04170 ast_mutex_lock(&i->lock); 04171 04172 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO) 04173 tmp->tech = &sip_tech_info; 04174 else 04175 tmp->tech = &sip_tech; 04176 04177 /* Select our native format based on codec preference until we receive 04178 something from another device to the contrary. */ 04179 if (i->jointcapability) { /* The joint capabilities of us and peer */ 04180 what = i->jointcapability; 04181 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 04182 } else if (i->capability) { /* Our configured capability for this peer */ 04183 what = i->capability; 04184 video = i->capability & AST_FORMAT_VIDEO_MASK; 04185 } else { 04186 what = global_capability; /* Global codec support */ 04187 video = global_capability & AST_FORMAT_VIDEO_MASK; 04188 } 04189 04190 /* Set the native formats for audio and merge in video */ 04191 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video; 04192 if (option_debug > 2) { 04193 char buf[SIPBUFSIZE]; 04194 ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats)); 04195 ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability)); 04196 ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability)); 04197 ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1))); 04198 if (i->prefcodec) 04199 ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec)); 04200 } 04201 04202 /* XXX Why are we choosing a codec from the native formats?? */ 04203 fmt = ast_best_codec(tmp->nativeformats); 04204 04205 /* If we have a prefcodec setting, we have an inbound channel that set a 04206 preferred format for this call. Otherwise, we check the jointcapability 04207 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 04208 */ 04209 if (i->vrtp) { 04210 if (i->prefcodec) 04211 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 04212 else 04213 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 04214 } 04215 04216 if (option_debug > 2) { 04217 if (needvideo) 04218 ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n"); 04219 else 04220 ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n"); 04221 } 04222 04223 04224 04225 if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) { 04226 i->vad = ast_dsp_new(); 04227 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 04228 if (global_relaxdtmf) 04229 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 04230 } 04231 if (i->rtp) { 04232 tmp->fds[0] = ast_rtp_fd(i->rtp); 04233 tmp->fds[1] = ast_rtcp_fd(i->rtp); 04234 } 04235 if (needvideo && i->vrtp) { 04236 tmp->fds[2] = ast_rtp_fd(i->vrtp); 04237 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 04238 } 04239 if (i->udptl) { 04240 tmp->fds[5] = ast_udptl_fd(i->udptl); 04241 } 04242 if (state == AST_STATE_RING) 04243 tmp->rings = 1; 04244 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 04245 tmp->writeformat = fmt; 04246 tmp->rawwriteformat = fmt; 04247 tmp->readformat = fmt; 04248 tmp->rawreadformat = fmt; 04249 tmp->tech_pvt = i; 04250 04251 tmp->callgroup = i->callgroup; 04252 tmp->pickupgroup = i->pickupgroup; 04253 tmp->cid.cid_pres = i->callingpres; 04254 if (!ast_strlen_zero(i->accountcode)) 04255 ast_string_field_set(tmp, accountcode, i->accountcode); 04256 if (i->amaflags) 04257 tmp->amaflags = i->amaflags; 04258 if (!ast_strlen_zero(i->language)) 04259 ast_string_field_set(tmp, language, i->language); 04260 i->owner = tmp; 04261 ast_module_ref(ast_module_info->self); 04262 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 04263 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 04264 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 04265 * structure so that there aren't issues when forming URI's 04266 */ 04267 decoded_exten = ast_strdupa(i->exten); 04268 ast_uri_decode(decoded_exten); 04269 ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten)); 04270 04271 /* Don't use ast_set_callerid() here because it will 04272 * generate an unnecessary NewCallerID event */ 04273 tmp->cid.cid_ani = ast_strdup(i->cid_num); 04274 if (!ast_strlen_zero(i->rdnis)) 04275 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 04276 04277 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 04278 tmp->cid.cid_dnid = ast_strdup(i->exten); 04279 04280 tmp->priority = 1; 04281 if (!ast_strlen_zero(i->uri)) 04282 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 04283 if (!ast_strlen_zero(i->domain)) 04284 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 04285 if (!ast_strlen_zero(i->useragent)) 04286 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 04287 if (!ast_strlen_zero(i->callid)) 04288 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 04289 if (i->rtp) 04290 ast_jb_configure(tmp, &global_jbconf); 04291 04292 /* Set channel variables for this call from configuration */ 04293 for (v = i->chanvars ; v ; v = v->next) 04294 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04295 04296 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 04297 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04298 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 04299 ast_hangup(tmp); 04300 tmp = NULL; 04301 } 04302 04303 if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY)) 04304 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 04305 04306 return tmp; 04307 }
static int sip_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP Debugging in CLI.
Definition at line 11930 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11931 { 11932 if (argc != 4) 11933 return RESULT_SHOWUSAGE; 11934 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11935 ast_cli(fd, "SIP Debugging Disabled\n"); 11936 return RESULT_SUCCESS; 11937 }
static int sip_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11939 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11940 { 11941 if (argc != 3) 11942 return RESULT_SHOWUSAGE; 11943 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11944 ast_cli(fd, "SIP Debugging Disabled\n"); 11945 return RESULT_SUCCESS; 11946 }
static int sip_no_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP History logging (CLI).
Definition at line 11960 of file chan_sip.c.
References ast_cli(), FALSE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
11961 { 11962 if (argc != 3) { 11963 return RESULT_SHOWUSAGE; 11964 } 11965 recordhistory = FALSE; 11966 ast_cli(fd, "SIP History Recording Disabled\n"); 11967 return RESULT_SUCCESS; 11968 }
static int sip_notify | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Cli command to send SIP notify to peer.
Definition at line 11874 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.
11875 { 11876 struct ast_variable *varlist; 11877 int i; 11878 11879 if (argc < 4) 11880 return RESULT_SHOWUSAGE; 11881 11882 if (!notify_types) { 11883 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 11884 return RESULT_FAILURE; 11885 } 11886 11887 varlist = ast_variable_browse(notify_types, argv[2]); 11888 11889 if (!varlist) { 11890 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 11891 return RESULT_FAILURE; 11892 } 11893 11894 for (i = 3; i < argc; i++) { 11895 struct sip_pvt *p; 11896 struct sip_request req; 11897 struct ast_variable *var; 11898 11899 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { 11900 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 11901 return RESULT_FAILURE; 11902 } 11903 11904 if (create_addr(p, argv[i], NULL)) { 11905 /* Maybe they're not registered, etc. */ 11906 sip_destroy(p); 11907 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 11908 continue; 11909 } 11910 11911 initreqprep(&req, p, SIP_NOTIFY); 11912 11913 for (var = varlist; var; var = var->next) 11914 add_header(&req, var->name, ast_unescape_semicolon(var->value)); 11915 11916 /* Recalculate our side, and recalculate Call ID */ 11917 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 11918 p->ourip = __ourip; 11919 build_via(p); 11920 build_callid_pvt(p); 11921 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 11922 transmit_sip_request(p, &req); 11923 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11924 } 11925 11926 return RESULT_SUCCESS; 11927 }
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 13718 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().
13719 { 13720 struct sip_dual *d; 13721 struct ast_channel *transferee, *transferer; 13722 /* Chan2m: The transferer, chan1m: The transferee */ 13723 pthread_t th; 13724 13725 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 13726 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); 13727 if ((!transferer) || (!transferee)) { 13728 if (transferee) { 13729 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13730 ast_hangup(transferee); 13731 } 13732 if (transferer) { 13733 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13734 ast_hangup(transferer); 13735 } 13736 return -1; 13737 } 13738 13739 /* Make formats okay */ 13740 transferee->readformat = chan1->readformat; 13741 transferee->writeformat = chan1->writeformat; 13742 13743 /* Prepare for taking over the channel */ 13744 ast_channel_masquerade(transferee, chan1); 13745 13746 /* Setup the extensions and such */ 13747 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 13748 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 13749 transferee->priority = chan1->priority; 13750 13751 /* We make a clone of the peer channel too, so we can play 13752 back the announcement */ 13753 13754 /* Make formats okay */ 13755 transferer->readformat = chan2->readformat; 13756 transferer->writeformat = chan2->writeformat; 13757 13758 /* Prepare for taking over the channel. Go ahead and grab this channel 13759 * lock here to avoid a deadlock with callbacks into the channel driver 13760 * that hold the channel lock and want the pvt lock. */ 13761 while (ast_channel_trylock(chan2)) { 13762 struct sip_pvt *pvt = chan2->tech_pvt; 13763 DEADLOCK_AVOIDANCE(&pvt->lock); 13764 } 13765 ast_channel_masquerade(transferer, chan2); 13766 ast_channel_unlock(chan2); 13767 13768 /* Setup the extensions and such */ 13769 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 13770 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 13771 transferer->priority = chan2->priority; 13772 13773 ast_channel_lock(transferer); 13774 if (ast_do_masquerade(transferer)) { 13775 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 13776 ast_channel_unlock(transferer); 13777 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13778 ast_hangup(transferer); 13779 return -1; 13780 } 13781 ast_channel_unlock(transferer); 13782 if (!transferer || !transferee) { 13783 if (!transferer) { 13784 if (option_debug) 13785 ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n"); 13786 } 13787 if (!transferee) { 13788 if (option_debug) 13789 ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n"); 13790 } 13791 return -1; 13792 } 13793 if ((d = ast_calloc(1, sizeof(*d)))) { 13794 pthread_attr_t attr; 13795 13796 pthread_attr_init(&attr); 13797 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 13798 13799 /* Save original request for followup */ 13800 copy_request(&d->req, req); 13801 d->chan1 = transferee; /* Transferee */ 13802 d->chan2 = transferer; /* Transferer */ 13803 d->seqno = seqno; 13804 if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) { 13805 /* Could not start thread */ 13806 free(d); /* We don't need it anymore. If thread is created, d will be free'd 13807 by sip_park_thread() */ 13808 pthread_attr_destroy(&attr); 13809 return 0; 13810 } 13811 pthread_attr_destroy(&attr); 13812 } 13813 return -1; 13814 }
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 13651 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().
13652 { 13653 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 13654 struct sip_dual *d; 13655 struct sip_request req; 13656 int ext; 13657 int res; 13658 13659 d = stuff; 13660 transferee = d->chan1; 13661 transferer = d->chan2; 13662 copy_request(&req, &d->req); 13663 13664 if (!transferee || !transferer) { 13665 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 13666 return NULL; 13667 } 13668 if (option_debug > 3) 13669 ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 13670 13671 ast_channel_lock(transferee); 13672 if (ast_do_masquerade(transferee)) { 13673 ast_log(LOG_WARNING, "Masquerade failed.\n"); 13674 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 13675 ast_channel_unlock(transferee); 13676 return NULL; 13677 } 13678 ast_channel_unlock(transferee); 13679 13680 res = ast_park_call(transferee, transferer, 0, &ext); 13681 13682 13683 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 13684 if (!res) { 13685 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 13686 } else { 13687 /* Then tell the transferer what happened */ 13688 sprintf(buf, "Call parked on extension '%d'", ext); 13689 transmit_message_with_text(transferer->tech_pvt, buf); 13690 } 13691 #endif 13692 13693 /* Any way back to the current call??? */ 13694 /* Transmit response to the REFER request */ 13695 transmit_response(transferer->tech_pvt, "202 Accepted", &req); 13696 if (!res) { 13697 /* Transfer succeeded */ 13698 append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext); 13699 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 13700 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 13701 ast_hangup(transferer); /* This will cause a BYE */ 13702 if (option_debug) 13703 ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext); 13704 } else { 13705 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 13706 append_history(transferer->tech_pvt, "SIPpark","Parking failed\n"); 13707 if (option_debug) 13708 ast_log(LOG_DEBUG, "SIP Call parked failed \n"); 13709 /* Do not hangup call */ 13710 } 13711 free(d); 13712 return NULL; 13713 }
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 8938 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().
08939 { 08940 struct sip_peer *peer = find_peer(p->peername, NULL, 1, 0); 08941 08942 if (!peer) 08943 return; 08944 08945 /* If they put someone on hold, increment the value... otherwise decrement it */ 08946 if (hold) 08947 peer->onHold++; 08948 else 08949 peer->onHold--; 08950 08951 /* Request device state update */ 08952 ast_device_state_changed("SIP/%s", peer->name); 08953 08954 return; 08955 }
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 18994 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().
18995 { 18996 int ms = 0; 18997 18998 if (!speerobjs) /* No peers, just give up */ 18999 return; 19000 19001 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 19002 ASTOBJ_WRLOCK(iterator); 19003 if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) { 19004 struct sip_peer *peer_ptr = iterator; 19005 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 19006 } 19007 ms += 100; 19008 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, ASTOBJ_REF(iterator)); 19009 if (iterator->pokeexpire == -1) { 19010 struct sip_peer *peer_ptr = iterator; 19011 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 19012 } 19013 ASTOBJ_UNLOCK(iterator); 19014 } while (0) 19015 ); 19016 }
static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 16842 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_test_flag, ast_update_realtime(), ASTOBJ_UNREF, sip_peer::call, DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, global_flags, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::name, sip_peer::pokeexpire, sched, sip_destroy(), sip_destroy_peer(), SIP_PAGE2_RTUPDATE, and sip_poke_peer_s().
Referenced by sip_poke_peer().
16843 { 16844 struct sip_peer *peer = (struct sip_peer *)data; 16845 16846 peer->pokeexpire = -1; 16847 if (peer->lastms > -1) { 16848 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 16849 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE)) { 16850 ast_update_realtime("sippeers", "name", peer->name, "lastms", "-1", NULL); 16851 } 16852 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 16853 } 16854 if (peer->call) 16855 sip_destroy(peer->call); 16856 peer->call = NULL; 16857 peer->lastms = -1; 16858 ast_device_state_changed("SIP/%s", peer->name); 16859 16860 /* This function gets called one place outside of the scheduler ... */ 16861 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16862 struct sip_peer *peer_ptr = peer; 16863 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16864 } 16865 16866 /* There is no need to ASTOBJ_REF() here. Just let the scheduled callback 16867 * inherit the reference that the current callback already has. */ 16868 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 16869 if (peer->pokeexpire == -1) { 16870 ASTOBJ_UNREF(peer, sip_destroy_peer); 16871 } 16872 16873 return 0; 16874 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 16879 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_poke_noanswer(), sipdebug, sip_peer::tohost, transmit_invite(), sip_pvt::username, and XMIT_ERROR.
Referenced by build_peer(), parse_register_contact(), reg_source_db(), and sip_poke_peer_s().
16880 { 16881 struct sip_pvt *p; 16882 int xmitres = 0; 16883 16884 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 16885 /* IF we have no IP, or this isn't to be monitored, return 16886 imeediately after clearing things out */ 16887 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16888 struct sip_peer *peer_ptr = peer; 16889 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16890 } 16891 peer->lastms = 0; 16892 peer->call = NULL; 16893 return 0; 16894 } 16895 if (peer->call) { 16896 if (sipdebug) 16897 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 16898 sip_destroy(peer->call); 16899 } 16900 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS))) 16901 return -1; 16902 16903 p->sa = peer->addr; 16904 p->recv = peer->addr; 16905 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 16906 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16907 16908 /* Send OPTIONs to peer's fullcontact */ 16909 if (!ast_strlen_zero(peer->fullcontact)) 16910 ast_string_field_set(p, fullcontact, peer->fullcontact); 16911 16912 if (!ast_strlen_zero(peer->tohost)) 16913 ast_string_field_set(p, tohost, peer->tohost); 16914 else 16915 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 16916 16917 /* Recalculate our side, and recalculate Call ID */ 16918 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16919 p->ourip = __ourip; 16920 build_via(p); 16921 build_callid_pvt(p); 16922 16923 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16924 struct sip_peer *peer_ptr = peer; 16925 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16926 } 16927 16928 p->relatedpeer = ASTOBJ_REF(peer); 16929 ast_set_flag(&p->flags[0], SIP_OUTGOING); 16930 #ifdef VOCAL_DATA_HACK 16931 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 16932 xmitres = transmit_invite(p, SIP_INVITE, 0, 2); 16933 #else 16934 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); 16935 #endif 16936 gettimeofday(&peer->ps, NULL); 16937 if (xmitres == XMIT_ERROR) { 16938 sip_poke_noanswer(ASTOBJ_REF(peer)); /* Immediately unreachable, network problems */ 16939 } else { 16940 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16941 struct sip_peer *peer_ptr = peer; 16942 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16943 } 16944 peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, ASTOBJ_REF(peer)); 16945 if (peer->pokeexpire == -1) { 16946 struct sip_peer *peer_ptr = peer; 16947 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16948 } 16949 } 16950 16951 return 0; 16952 }
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 8267 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().
08268 { 08269 struct sip_peer *peer = (struct sip_peer *) data; 08270 08271 peer->pokeexpire = -1; 08272 08273 sip_poke_peer(peer); 08274 08275 ASTOBJ_UNREF(peer, sip_destroy_peer); 08276 08277 return 0; 08278 }
static int sip_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 10649 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.
10650 { 10651 struct sip_peer *peer; 10652 struct sip_user *user; 10653 int pruneuser = FALSE; 10654 int prunepeer = FALSE; 10655 int multi = FALSE; 10656 char *name = NULL; 10657 regex_t regexbuf; 10658 10659 switch (argc) { 10660 case 4: 10661 if (!strcasecmp(argv[3], "user")) 10662 return RESULT_SHOWUSAGE; 10663 if (!strcasecmp(argv[3], "peer")) 10664 return RESULT_SHOWUSAGE; 10665 if (!strcasecmp(argv[3], "like")) 10666 return RESULT_SHOWUSAGE; 10667 if (!strcasecmp(argv[3], "all")) { 10668 multi = TRUE; 10669 pruneuser = prunepeer = TRUE; 10670 } else { 10671 pruneuser = prunepeer = TRUE; 10672 name = argv[3]; 10673 } 10674 break; 10675 case 5: 10676 if (!strcasecmp(argv[4], "like")) 10677 return RESULT_SHOWUSAGE; 10678 if (!strcasecmp(argv[3], "all")) 10679 return RESULT_SHOWUSAGE; 10680 if (!strcasecmp(argv[3], "like")) { 10681 multi = TRUE; 10682 name = argv[4]; 10683 pruneuser = prunepeer = TRUE; 10684 } else if (!strcasecmp(argv[3], "user")) { 10685 pruneuser = TRUE; 10686 if (!strcasecmp(argv[4], "all")) 10687 multi = TRUE; 10688 else 10689 name = argv[4]; 10690 } else if (!strcasecmp(argv[3], "peer")) { 10691 prunepeer = TRUE; 10692 if (!strcasecmp(argv[4], "all")) 10693 multi = TRUE; 10694 else 10695 name = argv[4]; 10696 } else 10697 return RESULT_SHOWUSAGE; 10698 break; 10699 case 6: 10700 if (strcasecmp(argv[4], "like")) 10701 return RESULT_SHOWUSAGE; 10702 if (!strcasecmp(argv[3], "user")) { 10703 pruneuser = TRUE; 10704 name = argv[5]; 10705 } else if (!strcasecmp(argv[3], "peer")) { 10706 prunepeer = TRUE; 10707 name = argv[5]; 10708 } else 10709 return RESULT_SHOWUSAGE; 10710 break; 10711 default: 10712 return RESULT_SHOWUSAGE; 10713 } 10714 10715 if (multi && name) { 10716 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 10717 return RESULT_SHOWUSAGE; 10718 } 10719 10720 if (multi) { 10721 if (prunepeer) { 10722 int pruned = 0; 10723 10724 ASTOBJ_CONTAINER_WRLOCK(&peerl); 10725 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10726 ASTOBJ_RDLOCK(iterator); 10727 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10728 ASTOBJ_UNLOCK(iterator); 10729 continue; 10730 }; 10731 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10732 ASTOBJ_MARK(iterator); 10733 pruned++; 10734 } 10735 ASTOBJ_UNLOCK(iterator); 10736 } while (0) ); 10737 if (pruned) { 10738 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 10739 ast_cli(fd, "%d peers pruned.\n", pruned); 10740 } else 10741 ast_cli(fd, "No peers found to prune.\n"); 10742 ASTOBJ_CONTAINER_UNLOCK(&peerl); 10743 } 10744 if (pruneuser) { 10745 int pruned = 0; 10746 10747 ASTOBJ_CONTAINER_WRLOCK(&userl); 10748 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10749 ASTOBJ_RDLOCK(iterator); 10750 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10751 ASTOBJ_UNLOCK(iterator); 10752 continue; 10753 }; 10754 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10755 ASTOBJ_MARK(iterator); 10756 pruned++; 10757 } 10758 ASTOBJ_UNLOCK(iterator); 10759 } while (0) ); 10760 if (pruned) { 10761 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 10762 ast_cli(fd, "%d users pruned.\n", pruned); 10763 } else 10764 ast_cli(fd, "No users found to prune.\n"); 10765 ASTOBJ_CONTAINER_UNLOCK(&userl); 10766 } 10767 } else { 10768 if (prunepeer) { 10769 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 10770 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10771 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 10772 ASTOBJ_CONTAINER_LINK(&peerl, peer); 10773 } else 10774 ast_cli(fd, "Peer '%s' pruned.\n", name); 10775 ASTOBJ_UNREF(peer, sip_destroy_peer); 10776 } else 10777 ast_cli(fd, "Peer '%s' not found.\n", name); 10778 } 10779 if (pruneuser) { 10780 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 10781 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10782 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 10783 ASTOBJ_CONTAINER_LINK(&userl, user); 10784 } else 10785 ast_cli(fd, "User '%s' pruned.\n", name); 10786 ASTOBJ_UNREF(user, sip_destroy_user); 10787 } else 10788 ast_cli(fd, "User '%s' not found.\n", name); 10789 } 10790 } 10791 10792 return RESULT_SUCCESS; 10793 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static] |
Read SIP RTP from channel.
Definition at line 4512 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().
04513 { 04514 struct ast_frame *fr; 04515 struct sip_pvt *p = ast->tech_pvt; 04516 int faxdetected = FALSE; 04517 04518 ast_mutex_lock(&p->lock); 04519 fr = sip_rtp_read(ast, p, &faxdetected); 04520 p->lastrtprx = time(NULL); 04521 04522 /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */ 04523 /* 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 */ 04524 if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) { 04525 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 04526 if (!p->pendinginvite) { 04527 if (option_debug > 2) 04528 ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name); 04529 p->t38.state = T38_LOCAL_REINVITE; 04530 transmit_reinvite_with_t38_sdp(p); 04531 if (option_debug > 1) 04532 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name); 04533 } 04534 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04535 if (option_debug > 2) 04536 ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name); 04537 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04538 } 04539 } 04540 04541 /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */ 04542 if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) { 04543 fr = &ast_null_frame; 04544 } 04545 04546 ast_mutex_unlock(&p->lock); 04547 return fr; 04548 }
static struct sockaddr_in * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static] |
The real destination address for a write.
Definition at line 1774 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().
01775 { 01776 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa; 01777 }
static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 8071 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().
08072 { 08073 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 08074 return p->refer ? 1 : 0; 08075 }
static int sip_reg_timeout | ( | const void * | data | ) | [static] |
Registration timeout, register again.
Definition at line 7808 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(), sip_registry::needdns, 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(), TRUE, and sip_registry::username.
Referenced by __sip_xmit(), and transmit_register().
07809 { 07810 07811 /* if we are here, our registration timed out, so we'll just do it over */ 07812 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 07813 struct sip_pvt *p; 07814 int res; 07815 07816 /* if we couldn't get a reference to the registry object, punt */ 07817 if (!r) 07818 return 0; 07819 07820 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 07821 if (r->call) { 07822 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 07823 in the single SIP manager thread. */ 07824 p = r->call; 07825 ast_mutex_lock(&p->lock); 07826 if (p->registry) 07827 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 07828 r->call = NULL; 07829 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 07830 /* Pretend to ACK anything just in case */ 07831 __sip_pretend_ack(p); 07832 ast_mutex_unlock(&p->lock); 07833 } 07834 /* If we have a limit, stop registration and give up */ 07835 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 07836 /* Ok, enough is enough. Don't try any more */ 07837 /* We could add an external notification here... 07838 steal it from app_voicemail :-) */ 07839 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 07840 r->regstate = REG_STATE_FAILED; 07841 } else { 07842 r->regstate = REG_STATE_UNREGISTERED; 07843 r->timeout = -1; 07844 r->needdns = TRUE; 07845 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 07846 } 07847 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)); 07848 ASTOBJ_UNREF(r, sip_registry_destroy); 07849 return 0; 07850 }
static int sip_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 4851 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(), TRUE, and username.
04852 { 04853 struct sip_registry *reg; 04854 int portnum = 0; 04855 char username[256] = ""; 04856 char *hostname=NULL, *secret=NULL, *authuser=NULL; 04857 char *porta=NULL; 04858 char *contact=NULL; 04859 04860 if (!value) 04861 return -1; 04862 ast_copy_string(username, value, sizeof(username)); 04863 /* First split around the last '@' then parse the two components. */ 04864 hostname = strrchr(username, '@'); /* allow @ in the first part */ 04865 if (hostname) 04866 *hostname++ = '\0'; 04867 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 04868 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 04869 return -1; 04870 } 04871 /* split user[:secret[:authuser]] */ 04872 secret = strchr(username, ':'); 04873 if (secret) { 04874 *secret++ = '\0'; 04875 authuser = strchr(secret, ':'); 04876 if (authuser) 04877 *authuser++ = '\0'; 04878 } 04879 /* split host[:port][/contact] */ 04880 contact = strchr(hostname, '/'); 04881 if (contact) 04882 *contact++ = '\0'; 04883 if (ast_strlen_zero(contact)) 04884 contact = "s"; 04885 porta = strchr(hostname, ':'); 04886 if (porta) { 04887 *porta++ = '\0'; 04888 portnum = atoi(porta); 04889 if (portnum == 0) { 04890 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 04891 return -1; 04892 } 04893 } 04894 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 04895 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 04896 return -1; 04897 } 04898 04899 if (ast_string_field_init(reg, 256)) { 04900 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 04901 free(reg); 04902 return -1; 04903 } 04904 04905 regobjs++; 04906 ASTOBJ_INIT(reg); 04907 ast_string_field_set(reg, contact, contact); 04908 if (!ast_strlen_zero(username)) 04909 ast_string_field_set(reg, username, username); 04910 if (hostname) 04911 ast_string_field_set(reg, hostname, hostname); 04912 if (authuser) 04913 ast_string_field_set(reg, authuser, authuser); 04914 if (secret) 04915 ast_string_field_set(reg, secret, secret); 04916 reg->expire = -1; 04917 reg->timeout = -1; 04918 reg->refresh = default_expiry; 04919 reg->portno = portnum; 04920 reg->callid_valid = FALSE; 04921 reg->ocseq = INITIAL_CSEQ; 04922 reg->needdns = TRUE; 04923 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 04924 ASTOBJ_UNREF(reg,sip_registry_destroy); 04925 return 0; 04926 }
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 3127 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().
03128 { 03129 /* Really delete */ 03130 if (option_debug > 2) 03131 ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 03132 03133 if (reg->call) { 03134 /* Clear registry before destroying to ensure 03135 we don't get reentered trying to grab the registry lock */ 03136 reg->call->registry = NULL; 03137 if (option_debug > 2) 03138 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 03139 sip_destroy(reg->call); 03140 } 03141 AST_SCHED_DEL(sched, reg->expire); 03142 AST_SCHED_DEL(sched, reg->timeout); 03143 ast_string_field_free_memory(reg); 03144 regobjs--; 03145 free(reg); 03146 03147 }
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 12604 of file chan_sip.c.
References ast_mutex_lock, ast_mutex_unlock, ast_set_flag, check_pendings(), sip_pvt::flags, sip_pvt::lock, SIP_NEEDREINVITE, and sip_pvt::waitid.
Referenced by handle_response_invite().
12605 { 12606 struct sip_pvt *p = (struct sip_pvt *) data; 12607 12608 ast_mutex_lock(&p->lock); /* called from schedule thread which requires a lock */ 12609 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 12610 p->waitid = -1; 12611 check_pendings(p); 12612 ast_mutex_unlock(&p->lock); 12613 return 0; 12614 }
static int sip_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Force reload of module from cli.
Definition at line 19062 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().
19063 { 19064 ast_mutex_lock(&sip_reload_lock); 19065 if (sip_reloading) 19066 ast_verbose("Previous SIP reload not yet done\n"); 19067 else { 19068 sip_reloading = TRUE; 19069 if (fd) 19070 sip_reloadreason = CHANNEL_CLI_RELOAD; 19071 else 19072 sip_reloadreason = CHANNEL_MODULE_RELOAD; 19073 } 19074 ast_mutex_unlock(&sip_reload_lock); 19075 restart_monitor(); 19076 19077 return 0; 19078 }
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 17064 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.
17065 { 17066 int oldformat; 17067 struct sip_pvt *p; 17068 struct ast_channel *tmpc = NULL; 17069 char *ext, *host; 17070 char tmp[256]; 17071 char *dest = data; 17072 17073 oldformat = format; 17074 if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { 17075 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)); 17076 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 17077 return NULL; 17078 } 17079 if (option_debug) 17080 ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 17081 17082 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { 17083 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data); 17084 *cause = AST_CAUSE_SWITCH_CONGESTION; 17085 return NULL; 17086 } 17087 17088 ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL); 17089 17090 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 17091 sip_destroy(p); 17092 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 17093 *cause = AST_CAUSE_SWITCH_CONGESTION; 17094 return NULL; 17095 } 17096 17097 ast_copy_string(tmp, dest, sizeof(tmp)); 17098 host = strchr(tmp, '@'); 17099 if (host) { 17100 *host++ = '\0'; 17101 ext = tmp; 17102 } else { 17103 ext = strchr(tmp, '/'); 17104 if (ext) 17105 *ext++ = '\0'; 17106 host = tmp; 17107 } 17108 17109 if (create_addr(p, host, NULL)) { 17110 *cause = AST_CAUSE_UNREGISTERED; 17111 if (option_debug > 2) 17112 ast_log(LOG_DEBUG, "Cant create SIP call - target device not registered\n"); 17113 sip_destroy(p); 17114 return NULL; 17115 } 17116 if (ast_strlen_zero(p->peername) && ext) 17117 ast_string_field_set(p, peername, ext); 17118 /* Recalculate our side, and recalculate Call ID */ 17119 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 17120 p->ourip = __ourip; 17121 build_via(p); 17122 build_callid_pvt(p); 17123 17124 /* We have an extension to call, don't use the full contact here */ 17125 /* This to enable dialing registered peers with extension dialling, 17126 like SIP/peername/extension 17127 SIP/peername will still use the full contact */ 17128 if (ext) { 17129 ast_string_field_set(p, username, ext); 17130 ast_string_field_free(p, fullcontact); 17131 } 17132 #if 0 17133 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 17134 #endif 17135 p->prefcodec = oldformat; /* Format for this call */ 17136 ast_mutex_lock(&p->lock); 17137 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 17138 ast_mutex_unlock(&p->lock); 17139 if (!tmpc) 17140 sip_destroy(p); 17141 ast_update_use_count(); 17142 restart_monitor(); 17143 return tmpc; 17144 }
static int sip_reregister | ( | const void * | data | ) | [static] |
Update registration with SIP Proxy.
Definition at line 7776 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().
07777 { 07778 /* if we are here, we know that we need to reregister. */ 07779 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 07780 07781 /* if we couldn't get a reference to the registry object, punt */ 07782 if (!r) 07783 return 0; 07784 07785 if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 07786 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 07787 /* Since registry's are only added/removed by the the monitor thread, this 07788 may be overkill to reference/dereference at all here */ 07789 if (sipdebug) 07790 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 07791 07792 r->expire = -1; 07793 __sip_do_register(r); 07794 ASTOBJ_UNREF(r, sip_registry_destroy); 07795 return 0; 07796 }
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 4440 of file chan_sip.c.
References ast_dsp_process(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, 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().
04441 { 04442 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 04443 struct ast_frame *f; 04444 04445 if (!p->rtp) { 04446 /* We have no RTP allocated for this channel */ 04447 return &ast_null_frame; 04448 } 04449 04450 switch(ast->fdno) { 04451 case 0: 04452 f = ast_rtp_read(p->rtp); /* RTP Audio */ 04453 break; 04454 case 1: 04455 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 04456 break; 04457 case 2: 04458 f = ast_rtp_read(p->vrtp); /* RTP Video */ 04459 break; 04460 case 3: 04461 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 04462 break; 04463 case 5: 04464 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 04465 break; 04466 default: 04467 f = &ast_null_frame; 04468 } 04469 /* Don't forward RFC2833 if we're not supposed to */ 04470 if (f && (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && 04471 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) { 04472 ast_log(LOG_DEBUG,"Ignoring DTMF (%c) RTP frame because dtmfmode is not RFC2833\n", f->subclass); 04473 return &ast_null_frame; 04474 } 04475 04476 /* We already hold the channel lock */ 04477 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 04478 return f; 04479 04480 if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 04481 if (!(f->subclass & p->jointcapability)) { 04482 if (option_debug) { 04483 ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n", 04484 ast_getformatname(f->subclass), p->owner->name); 04485 } 04486 return &ast_null_frame; 04487 } 04488 if (option_debug) 04489 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 04490 p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; 04491 ast_set_read_format(p->owner, p->owner->readformat); 04492 ast_set_write_format(p->owner, p->owner->writeformat); 04493 } 04494 04495 if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 04496 f = ast_dsp_process(p->owner, p->vad, f); 04497 if (f && f->frametype == AST_FRAME_DTMF) { 04498 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') { 04499 if (option_debug) 04500 ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name); 04501 *faxdetect = 1; 04502 } else if (option_debug) { 04503 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 04504 } 04505 } 04506 } 04507 04508 return f; 04509 }
static void sip_scheddestroy | ( | struct sip_pvt * | p, | |
int | ms | |||
) | [static] |
Schedule destruction of SIP dialog.
Definition at line 2159 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(), sip_sipredirect(), and transmit_fake_auth_response().
02160 { 02161 if (ms < 0) { 02162 if (p->timer_t1 == 0) 02163 p->timer_t1 = 500; /* Set timer T1 if not set (RFC 3261) */ 02164 ms = p->timer_t1 * 64; 02165 } 02166 if (sip_debug_test_pvt(p)) 02167 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 02168 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 02169 append_history(p, "SchedDestroy", "%d ms", ms); 02170 02171 AST_SCHED_DEL(sched, p->autokillid); 02172 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 02173 }
static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 19019 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().
19020 { 19021 int ms; 19022 int regspacing; 19023 if (!regobjs) 19024 return; 19025 regspacing = default_expiry * 1000/regobjs; 19026 if (regspacing > 100) 19027 regspacing = 100; 19028 ms = regspacing; 19029 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 19030 ASTOBJ_WRLOCK(iterator); 19031 AST_SCHED_DEL(sched, iterator->expire); 19032 ms += regspacing; 19033 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 19034 ASTOBJ_UNLOCK(iterator); 19035 } while (0) 19036 ); 19037 }
static int sip_send_mwi_to_peer | ( | struct sip_peer * | peer, | |
int | force | |||
) | [static] |
Send message waiting indication to alert peer that they've got voicemail.
Definition at line 16572 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().
16573 { 16574 /* Called with peerl lock, but releases it */ 16575 struct sip_pvt *p; 16576 int newmsgs, oldmsgs; 16577 16578 /* Do we have an IP address? If not, skip this peer */ 16579 if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 16580 return 0; 16581 16582 /* Check for messages */ 16583 ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs); 16584 16585 peer->lastmsgcheck = time(NULL); 16586 16587 /* Return now if it's the same thing we told them last time */ 16588 if (!force && ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) { 16589 return 0; 16590 } 16591 16592 16593 peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)); 16594 16595 if (peer->mwipvt) { 16596 /* Base message on subscription */ 16597 p = peer->mwipvt; 16598 } else { 16599 /* Build temporary dialog for this message */ 16600 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 16601 return -1; 16602 if (create_addr_from_peer(p, peer)) { 16603 /* Maybe they're not registered, etc. */ 16604 sip_destroy(p); 16605 return 0; 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 /* Destroy this session after 32 secs */ 16613 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16614 } 16615 /* Send MWI */ 16616 ast_set_flag(&p->flags[0], SIP_OUTGOING); 16617 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 16618 return 0; 16619 }
static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 3937 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.
03938 { 03939 struct sip_pvt *p = ast->tech_pvt; 03940 int res = 0; 03941 03942 ast_mutex_lock(&p->lock); 03943 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03944 case SIP_DTMF_INBAND: 03945 res = -1; /* Tell Asterisk to generate inband indications */ 03946 break; 03947 case SIP_DTMF_RFC2833: 03948 if (p->rtp) 03949 ast_rtp_senddigit_begin(p->rtp, digit); 03950 break; 03951 default: 03952 break; 03953 } 03954 ast_mutex_unlock(&p->lock); 03955 03956 return res; 03957 }
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 3961 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().
03962 { 03963 struct sip_pvt *p = ast->tech_pvt; 03964 int res = 0; 03965 03966 ast_mutex_lock(&p->lock); 03967 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03968 case SIP_DTMF_INFO: 03969 transmit_info_with_digit(p, digit, duration); 03970 break; 03971 case SIP_DTMF_RFC2833: 03972 if (p->rtp) 03973 ast_rtp_senddigit_end(p->rtp, digit); 03974 break; 03975 case SIP_DTMF_INBAND: 03976 res = -1; /* Tell Asterisk to stop inband indications */ 03977 break; 03978 } 03979 ast_mutex_unlock(&p->lock); 03980 03981 return res; 03982 }
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 2418 of file chan_sip.c.
References ast_verbose(), debug, ast_channel::name, sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().
02419 { 02420 struct sip_pvt *p = ast->tech_pvt; 02421 int debug = sip_debug_test_pvt(p); 02422 02423 if (debug) 02424 ast_verbose("Sending text %s on %s\n", text, ast->name); 02425 if (!p) 02426 return -1; 02427 /* NOT ast_strlen_zero, because a zero-length message is specifically 02428 * allowed by RFC 3428 (See section 10, Examples) */ 02429 if (!text) 02430 return 0; 02431 if (debug) 02432 ast_verbose("Really sending text %s on %s\n", text, ast->name); 02433 transmit_message_with_text(p, text); 02434 return 0; 02435 }
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 18749 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), 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().
18750 { 18751 struct sip_pvt *p; 18752 int changed = 0; 18753 18754 p = chan->tech_pvt; 18755 if (!p) 18756 return -1; 18757 18758 /* Disable early RTP bridge */ 18759 if (!ast_bridged_channel(chan) && !global_directrtpsetup) /* We are in early state */ 18760 return 0; 18761 18762 ast_mutex_lock(&p->lock); 18763 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 18764 /* If we're destroyed, don't bother */ 18765 ast_mutex_unlock(&p->lock); 18766 return 0; 18767 } 18768 18769 /* if this peer cannot handle reinvites of the media stream to devices 18770 that are known to be behind a NAT, then stop the process now 18771 */ 18772 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 18773 ast_mutex_unlock(&p->lock); 18774 return 0; 18775 } 18776 18777 if (rtp) { 18778 changed |= ast_rtp_get_peer(rtp, &p->redirip); 18779 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 18780 memset(&p->redirip, 0, sizeof(p->redirip)); 18781 changed = 1; 18782 } 18783 if (vrtp) { 18784 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 18785 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 18786 memset(&p->vredirip, 0, sizeof(p->vredirip)); 18787 changed = 1; 18788 } 18789 if (codecs) { 18790 if (p->redircodecs != codecs && (p->jointcapability & codecs) != p->jointcapability) { 18791 p->redircodecs = codecs; 18792 p->jointcapability &= codecs; 18793 p->capability &= codecs; 18794 changed = 1; 18795 } 18796 } 18797 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 18798 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 18799 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 18800 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 18801 if (option_debug) 18802 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)); 18803 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 18804 if (option_debug > 2) { 18805 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)); 18806 } 18807 transmit_reinvite_with_sdp(p); 18808 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18809 if (option_debug > 2) { 18810 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)); 18811 } 18812 /* We have a pending Invite. Send re-invite when we're done with the invite */ 18813 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18814 } 18815 } 18816 /* Reset lastrtprx timer */ 18817 p->lastrtprx = p->lastrtptx = time(NULL); 18818 ast_mutex_unlock(&p->lock); 18819 return 0; 18820 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 18576 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.
18577 { 18578 struct sip_pvt *p; 18579 18580 p = chan->tech_pvt; 18581 if (!p) 18582 return -1; 18583 ast_mutex_lock(&p->lock); 18584 if (udptl) 18585 ast_udptl_get_peer(udptl, &p->udptlredirip); 18586 else 18587 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18588 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 18589 if (!p->pendinginvite) { 18590 if (option_debug > 2) { 18591 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); 18592 } 18593 transmit_reinvite_with_t38_sdp(p); 18594 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18595 if (option_debug > 2) { 18596 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); 18597 } 18598 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18599 } 18600 } 18601 /* Reset lastrtprx timer */ 18602 p->lastrtprx = p->lastrtptx = time(NULL); 18603 ast_mutex_unlock(&p->lock); 18604 return 0; 18605 }
static int sip_show_channel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show details of one active dialog.
Definition at line 11529 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.
11530 { 11531 struct sip_pvt *cur; 11532 size_t len; 11533 int found = 0; 11534 11535 if (argc != 4) 11536 return RESULT_SHOWUSAGE; 11537 len = strlen(argv[3]); 11538 ast_mutex_lock(&iflock); 11539 for (cur = iflist; cur; cur = cur->next) { 11540 if (!strncasecmp(cur->callid, argv[3], len)) { 11541 char formatbuf[SIPBUFSIZE/2]; 11542 ast_cli(fd,"\n"); 11543 if (cur->subscribed != NONE) 11544 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 11545 else 11546 ast_cli(fd, " * SIP Call\n"); 11547 ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 11548 ast_cli(fd, " Call-ID: %s\n", cur->callid); 11549 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 11550 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 11551 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 11552 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 11553 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 11554 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 11555 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 11556 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 11557 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 11558 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 11559 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 11560 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)" ); 11561 ast_cli(fd, " Our Tag: %s\n", cur->tag); 11562 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 11563 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 11564 if (!ast_strlen_zero(cur->username)) 11565 ast_cli(fd, " Username: %s\n", cur->username); 11566 if (!ast_strlen_zero(cur->peername)) 11567 ast_cli(fd, " Peername: %s\n", cur->peername); 11568 if (!ast_strlen_zero(cur->uri)) 11569 ast_cli(fd, " Original uri: %s\n", cur->uri); 11570 if (!ast_strlen_zero(cur->cid_num)) 11571 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 11572 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 11573 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 11574 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 11575 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 11576 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 11577 ast_cli(fd, " SIP Options: "); 11578 if (cur->sipoptions) { 11579 int x; 11580 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 11581 if (cur->sipoptions & sip_options[x].id) 11582 ast_cli(fd, "%s ", sip_options[x].text); 11583 } 11584 } else 11585 ast_cli(fd, "(none)\n"); 11586 ast_cli(fd, "\n\n"); 11587 found++; 11588 } 11589 } 11590 ast_mutex_unlock(&iflock); 11591 if (!found) 11592 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11593 return RESULT_SUCCESS; 11594 }
static int sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP channels.
Definition at line 11315 of file chan_sip.c.
References __sip_show_channels().
11316 { 11317 return __sip_show_channels(fd, argc, argv, 0); 11318 }
static int sip_show_domains | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list local domains.
Definition at line 10827 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.
10828 { 10829 struct domain *d; 10830 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 10831 10832 if (AST_LIST_EMPTY(&domain_list)) { 10833 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 10834 return RESULT_SUCCESS; 10835 } else { 10836 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 10837 AST_LIST_LOCK(&domain_list); 10838 AST_LIST_TRAVERSE(&domain_list, d, list) 10839 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 10840 domain_mode_to_text(d->mode)); 10841 AST_LIST_UNLOCK(&domain_list); 10842 ast_cli(fd, "\n"); 10843 return RESULT_SUCCESS; 10844 } 10845 }
static int sip_show_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show history details of one dialog.
Definition at line 11597 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.
11598 { 11599 struct sip_pvt *cur; 11600 size_t len; 11601 int found = 0; 11602 11603 if (argc != 4) 11604 return RESULT_SHOWUSAGE; 11605 if (!recordhistory) 11606 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 11607 len = strlen(argv[3]); 11608 ast_mutex_lock(&iflock); 11609 for (cur = iflist; cur; cur = cur->next) { 11610 if (!strncasecmp(cur->callid, argv[3], len)) { 11611 struct sip_history *hist; 11612 int x = 0; 11613 11614 ast_cli(fd,"\n"); 11615 if (cur->subscribed != NONE) 11616 ast_cli(fd, " * Subscription\n"); 11617 else 11618 ast_cli(fd, " * SIP Call\n"); 11619 if (cur->history) 11620 AST_LIST_TRAVERSE(cur->history, hist, list) 11621 ast_cli(fd, "%d. %s\n", ++x, hist->event); 11622 if (x == 0) 11623 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 11624 found++; 11625 } 11626 } 11627 ast_mutex_unlock(&iflock); 11628 if (!found) 11629 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11630 return RESULT_SUCCESS; 11631 }
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 10252 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.
10253 { 10254 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 10255 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 10256 char ilimits[40]; 10257 char iused[40]; 10258 int showall = FALSE; 10259 10260 if (argc < 3) 10261 return RESULT_SHOWUSAGE; 10262 10263 if (argc == 4 && !strcmp(argv[3],"all")) 10264 showall = TRUE; 10265 10266 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 10267 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10268 ASTOBJ_RDLOCK(iterator); 10269 if (iterator->call_limit) 10270 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 10271 else 10272 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 10273 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 10274 if (showall || iterator->call_limit) 10275 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 10276 ASTOBJ_UNLOCK(iterator); 10277 } while (0) ); 10278 10279 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 10280 10281 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10282 ASTOBJ_RDLOCK(iterator); 10283 if (iterator->call_limit) 10284 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 10285 else 10286 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 10287 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 10288 if (showall || iterator->call_limit) 10289 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 10290 ASTOBJ_UNLOCK(iterator); 10291 } while (0) ); 10292 10293 return RESULT_SUCCESS; 10294 #undef FORMAT 10295 #undef FORMAT2 10296 }
static int sip_show_objects | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 10573 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
10574 { 10575 char tmp[256]; 10576 if (argc != 3) 10577 return RESULT_SHOWUSAGE; 10578 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 10579 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 10580 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 10581 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 10582 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 10583 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 10584 return RESULT_SUCCESS; 10585 }
static int sip_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 10879 of file chan_sip.c.
References _sip_show_peer().
10880 { 10881 return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); 10882 }
static int sip_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Show Peers command.
Definition at line 10429 of file chan_sip.c.
References _sip_show_peers().
10430 { 10431 return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); 10432 }
static int sip_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 11152 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.
11153 { 11154 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 11155 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 11156 char host[80]; 11157 char tmpdat[256]; 11158 struct tm tm; 11159 11160 11161 if (argc != 3) 11162 return RESULT_SHOWUSAGE; 11163 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 11164 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 11165 ASTOBJ_RDLOCK(iterator); 11166 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 11167 if (iterator->regtime) { 11168 ast_localtime(&iterator->regtime, &tm, NULL); 11169 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 11170 } else { 11171 tmpdat[0] = 0; 11172 } 11173 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 11174 ASTOBJ_UNLOCK(iterator); 11175 } while(0)); 11176 return RESULT_SUCCESS; 11177 #undef FORMAT 11178 #undef FORMAT2 11179 }
static int sip_show_settings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List global settings for the SIP channel.
Definition at line 11182 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().
11183 { 11184 int realtimepeers; 11185 int realtimeusers; 11186 char codec_buf[SIPBUFSIZE]; 11187 11188 realtimepeers = ast_check_realtime("sippeers"); 11189 realtimeusers = ast_check_realtime("sipusers"); 11190 11191 if (argc != 3) 11192 return RESULT_SHOWUSAGE; 11193 ast_cli(fd, "\n\nGlobal Settings:\n"); 11194 ast_cli(fd, "----------------\n"); 11195 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 11196 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 11197 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 11198 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 11199 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 11200 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 11201 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 11202 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 11203 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 11204 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 11205 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 11206 ast_cli(fd, " Our auth realm %s\n", global_realm); 11207 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 11208 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 11209 ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No"); 11210 ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No"); 11211 ast_cli(fd, " User Agent: %s\n", global_useragent); 11212 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 11213 ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 11214 ast_cli(fd, " Caller ID: %s\n", default_callerid); 11215 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 11216 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 11217 ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 11218 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 11219 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 11220 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 11221 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 11222 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 11223 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 11224 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 11225 #endif 11226 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 11227 if (!realtimepeers && !realtimeusers) 11228 ast_cli(fd, " SIP realtime: Disabled\n" ); 11229 else 11230 ast_cli(fd, " SIP realtime: Enabled\n" ); 11231 11232 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 11233 ast_cli(fd, "---------------------------\n"); 11234 ast_cli(fd, " Codecs: "); 11235 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 11236 ast_cli(fd, "%s\n", codec_buf); 11237 ast_cli(fd, " Codec Order: "); 11238 print_codec_to_cli(fd, &default_prefs); 11239 ast_cli(fd, "\n"); 11240 ast_cli(fd, " T1 minimum: %d\n", global_t1min); 11241 ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No"); 11242 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 11243 ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 11244 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 11245 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 11246 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 11247 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 11248 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 11249 ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); 11250 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 11251 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 11252 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 11253 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 11254 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 11255 ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No"); 11256 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 11257 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate); 11258 ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No"); 11259 ast_cli(fd, "\nDefault Settings:\n"); 11260 ast_cli(fd, "-----------------\n"); 11261 ast_cli(fd, " Context: %s\n", default_context); 11262 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 11263 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 11264 ast_cli(fd, " Qualify: %d\n", default_qualify); 11265 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 11266 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" ); 11267 ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)")); 11268 ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); 11269 ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); 11270 ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); 11271 11272 11273 if (realtimepeers || realtimeusers) { 11274 ast_cli(fd, "\nRealtime SIP Settings:\n"); 11275 ast_cli(fd, "----------------------\n"); 11276 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 11277 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 11278 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 11279 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 11280 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 11281 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 11282 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 11283 } 11284 ast_cli(fd, "\n----\n"); 11285 return RESULT_SUCCESS; 11286 }
static int sip_show_subscriptions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP subscriptions.
Definition at line 11321 of file chan_sip.c.
References __sip_show_channels().
11322 { 11323 return __sip_show_channels(fd, argc, argv, 1); 11324 }
static int sip_show_user | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one user in detail.
Definition at line 11097 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.
11098 { 11099 char cbuf[256]; 11100 struct sip_user *user; 11101 struct ast_variable *v; 11102 int load_realtime; 11103 11104 if (argc < 4) 11105 return RESULT_SHOWUSAGE; 11106 11107 /* Load from realtime storage? */ 11108 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 11109 11110 user = find_user(argv[3], load_realtime); 11111 if (user) { 11112 ast_cli(fd,"\n\n"); 11113 ast_cli(fd, " * Name : %s\n", user->name); 11114 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 11115 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 11116 ast_cli(fd, " Context : %s\n", user->context); 11117 ast_cli(fd, " Language : %s\n", user->language); 11118 if (!ast_strlen_zero(user->accountcode)) 11119 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 11120 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 11121 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 11122 ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 11123 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 11124 ast_cli(fd, " Call limit : %d\n", user->call_limit); 11125 ast_cli(fd, " Callgroup : "); 11126 print_group(fd, user->callgroup, 0); 11127 ast_cli(fd, " Pickupgroup : "); 11128 print_group(fd, user->pickupgroup, 0); 11129 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 11130 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 11131 ast_cli(fd, " Codec Order : ("); 11132 print_codec_to_cli(fd, &user->prefs); 11133 ast_cli(fd, ")\n"); 11134 11135 ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No"); 11136 if (user->chanvars) { 11137 ast_cli(fd, " Variables :\n"); 11138 for (v = user->chanvars ; v ; v = v->next) 11139 ast_cli(fd, " %s = %s\n", v->name, v->value); 11140 } 11141 ast_cli(fd,"\n"); 11142 ASTOBJ_UNREF(user,sip_destroy_user); 11143 } else { 11144 ast_cli(fd,"User %s not found.\n", argv[3]); 11145 ast_cli(fd,"\n"); 11146 } 11147 11148 return RESULT_SUCCESS; 11149 }
static int sip_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 10352 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.
10353 { 10354 regex_t regexbuf; 10355 int havepattern = FALSE; 10356 10357 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 10358 10359 switch (argc) { 10360 case 5: 10361 if (!strcasecmp(argv[3], "like")) { 10362 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 10363 return RESULT_SHOWUSAGE; 10364 havepattern = TRUE; 10365 } else 10366 return RESULT_SHOWUSAGE; 10367 case 3: 10368 break; 10369 default: 10370 return RESULT_SHOWUSAGE; 10371 } 10372 10373 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 10374 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10375 ASTOBJ_RDLOCK(iterator); 10376 10377 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10378 ASTOBJ_UNLOCK(iterator); 10379 continue; 10380 } 10381 10382 ast_cli(fd, FORMAT, iterator->name, 10383 iterator->secret, 10384 iterator->accountcode, 10385 iterator->context, 10386 iterator->ha ? "Yes" : "No", 10387 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 10388 ASTOBJ_UNLOCK(iterator); 10389 } while (0) 10390 ); 10391 10392 if (havepattern) 10393 regfree(®exbuf); 10394 10395 return RESULT_SUCCESS; 10396 #undef FORMAT 10397 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 18933 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().
18934 { 18935 char *cdest; 18936 char *extension, *host, *port; 18937 char tmp[80]; 18938 18939 cdest = ast_strdupa(dest); 18940 18941 extension = strsep(&cdest, "@"); 18942 host = strsep(&cdest, ":"); 18943 port = strsep(&cdest, ":"); 18944 if (ast_strlen_zero(extension)) { 18945 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 18946 return 0; 18947 } 18948 18949 /* we'll issue the redirect message here */ 18950 if (!host) { 18951 char *localtmp; 18952 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 18953 if (ast_strlen_zero(tmp)) { 18954 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 18955 return 0; 18956 } 18957 if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 18958 char lhost[80], lport[80]; 18959 memset(lhost, 0, sizeof(lhost)); 18960 memset(lport, 0, sizeof(lport)); 18961 localtmp++; 18962 /* This is okey because lhost and lport are as big as tmp */ 18963 sscanf(localtmp, "%80[^<>:; ]:%80[^<>:; ]", lhost, lport); 18964 if (ast_strlen_zero(lhost)) { 18965 ast_log(LOG_ERROR, "Can't find the host address\n"); 18966 return 0; 18967 } 18968 host = ast_strdupa(lhost); 18969 if (!ast_strlen_zero(lport)) { 18970 port = ast_strdupa(lport); 18971 } 18972 } 18973 } 18974 18975 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 18976 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 18977 18978 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 18979 sip_alreadygone(p); 18980 return 0; 18981 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
Transfer SIP call.
Definition at line 3985 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().
03986 { 03987 struct sip_pvt *p = ast->tech_pvt; 03988 int res; 03989 03990 if (dest == NULL) /* functions below do not take a NULL */ 03991 dest = ""; 03992 ast_mutex_lock(&p->lock); 03993 if (ast->_state == AST_STATE_RING) 03994 res = sip_sipredirect(p, dest); 03995 else 03996 res = transmit_refer(p, dest); 03997 ast_mutex_unlock(&p->lock); 03998 return res; 03999 }
static int sip_uri_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
Definition at line 14455 of file chan_sip.c.
References ast_strdupa, S_OR, sip_uri_headers_cmp(), and sip_uri_params_cmp().
Referenced by handle_request_invite().
14456 { 14457 char *uri1 = ast_strdupa(input1); 14458 char *uri2 = ast_strdupa(input2); 14459 char *host1; 14460 char *host2; 14461 char *params1; 14462 char *params2; 14463 char *headers1; 14464 char *headers2; 14465 14466 /* Strip off "sip:" from the URI. We know this is present 14467 * because it was checked back in parse_request() 14468 */ 14469 strsep(&uri1, ":"); 14470 strsep(&uri2, ":"); 14471 14472 if ((host1 = strchr(uri1, '@'))) { 14473 *host1++ = '\0'; 14474 } 14475 if ((host2 = strchr(uri2, '@'))) { 14476 *host2++ = '\0'; 14477 } 14478 14479 /* Check for mismatched username and passwords. This is the 14480 * only case-sensitive comparison of a SIP URI 14481 */ 14482 if ((host1 && !host2) || 14483 (host2 && !host1) || 14484 (host1 && host2 && strcmp(uri1, uri2))) { 14485 return 1; 14486 } 14487 14488 if (!host1) 14489 host1 = uri1; 14490 if (!host2) 14491 host2 = uri2; 14492 14493 /* Strip off the parameters and headers so we can compare 14494 * host and port 14495 */ 14496 14497 if ((params1 = strchr(host1, ';'))) { 14498 *params1++ = '\0'; 14499 } 14500 if ((params2 = strchr(host2, ';'))) { 14501 *params2++ = '\0'; 14502 } 14503 14504 /* Headers come after parameters, but there may be headers without 14505 * parameters, thus the S_OR 14506 */ 14507 if ((headers1 = strchr(S_OR(params1, host1), '?'))) { 14508 *headers1++ = '\0'; 14509 } 14510 if ((headers2 = strchr(S_OR(params2, host2), '?'))) { 14511 *headers2++ = '\0'; 14512 } 14513 14514 /* Now the host/port are properly isolated. We can get by with a string comparison 14515 * because the SIP URI checking rules have some interesting exceptions that make 14516 * this possible. I will note 2 in particular 14517 * 1. hostnames which resolve to the same IP address as well as a hostname and its 14518 * IP address are not considered a match with SIP URI's. 14519 * 2. If one URI specifies a port and the other does not, then the URIs do not match. 14520 * This includes if one URI explicitly contains port 5060 and the other implies it 14521 * by not having a port specified. 14522 */ 14523 14524 if (strcasecmp(host1, host2)) { 14525 return 1; 14526 } 14527 14528 /* Headers have easier rules to follow, so do those first */ 14529 if (sip_uri_headers_cmp(headers1, headers2)) { 14530 return 1; 14531 } 14532 14533 /* And now the parameters. Ugh */ 14534 return sip_uri_params_cmp(params1, params2); 14535 }
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 14409 of file chan_sip.c.
References ast_strdupa, and ast_strlen_zero().
Referenced by sip_uri_cmp().
14410 { 14411 char *headers1 = NULL; 14412 char *headers2 = NULL; 14413 int zerolength1 = 0; 14414 int zerolength2 = 0; 14415 int different = 0; 14416 char *header1; 14417 14418 if (ast_strlen_zero(input1)) { 14419 zerolength1 = 1; 14420 } else { 14421 headers1 = ast_strdupa(input1); 14422 } 14423 14424 if (ast_strlen_zero(input2)) { 14425 zerolength2 = 1; 14426 } else { 14427 headers2 = ast_strdupa(input2); 14428 } 14429 14430 if ((zerolength1 && !zerolength2) || 14431 (zerolength2 && !zerolength1)) 14432 return 1; 14433 14434 if (zerolength1 && zerolength2) 14435 return 0; 14436 14437 /* At this point, we can definitively state that both inputs are 14438 * not zero-length. First, one more optimization. If the length 14439 * of the headers is not equal, then we definitely have no match 14440 */ 14441 if (strlen(headers1) != strlen(headers2)) { 14442 return 1; 14443 } 14444 14445 for (header1 = strsep(&headers1, "&"); header1; header1 = strsep(&headers1, "&")) { 14446 if (!strcasestr(headers2, header1)) { 14447 different = 1; 14448 break; 14449 } 14450 } 14451 14452 return different; 14453 }
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 14269 of file chan_sip.c.
References ast_strdupa, and ast_strlen_zero().
Referenced by sip_uri_cmp().
14270 { 14271 char *params1 = NULL; 14272 char *params2 = NULL; 14273 char *pos1; 14274 char *pos2; 14275 int zerolength1 = 0; 14276 int zerolength2 = 0; 14277 int maddrmatch = 0; 14278 int ttlmatch = 0; 14279 int usermatch = 0; 14280 int methodmatch = 0; 14281 14282 if (ast_strlen_zero(input1)) { 14283 zerolength1 = 1; 14284 } else { 14285 params1 = ast_strdupa(input1); 14286 } 14287 if (ast_strlen_zero(input2)) { 14288 zerolength2 = 1; 14289 } else { 14290 params2 = ast_strdupa(input2); 14291 } 14292 14293 /*Quick optimization. If both params are zero-length, then 14294 * they match 14295 */ 14296 if (zerolength1 && zerolength2) { 14297 return 0; 14298 } 14299 14300 pos1 = params1; 14301 while (!ast_strlen_zero(pos1)) { 14302 char *name1 = pos1; 14303 char *value1 = strchr(pos1, '='); 14304 char *semicolon1 = strchr(pos1, ';'); 14305 int matched = 0; 14306 if (semicolon1) { 14307 *semicolon1++ = '\0'; 14308 } 14309 if (!value1) { 14310 goto fail; 14311 } 14312 *value1++ = '\0'; 14313 /* Checkpoint reached. We have the name and value parsed for param1 14314 * We have to duplicate params2 each time through the second loop 14315 * or else we can't search and replace the semicolons with \0 each 14316 * time 14317 */ 14318 pos2 = ast_strdupa(params2); 14319 while (!ast_strlen_zero(pos2)) { 14320 char *name2 = pos2; 14321 char *value2 = strchr(pos2, '='); 14322 char *semicolon2 = strchr(pos2, ';'); 14323 if (semicolon2) { 14324 *semicolon2++ = '\0'; 14325 } 14326 if (!value2) { 14327 goto fail; 14328 } 14329 *value2++ = '\0'; 14330 if (!strcasecmp(name1, name2)) { 14331 if (strcasecmp(value1, value2)) { 14332 goto fail; 14333 } else { 14334 matched = 1; 14335 break; 14336 } 14337 } 14338 pos2 = semicolon2; 14339 } 14340 /* Need to see if the parameter we're looking at is one of the 'must-match' parameters */ 14341 if (!strcasecmp(name1, "maddr")) { 14342 if (matched) { 14343 maddrmatch = 1; 14344 } else { 14345 goto fail; 14346 } 14347 } else if (!strcasecmp(name1, "ttl")) { 14348 if (matched) { 14349 ttlmatch = 1; 14350 } else { 14351 goto fail; 14352 } 14353 } else if (!strcasecmp(name1, "user")) { 14354 if (matched) { 14355 usermatch = 1; 14356 } else { 14357 goto fail; 14358 } 14359 } else if (!strcasecmp(name1, "method")) { 14360 if (matched) { 14361 methodmatch = 1; 14362 } else { 14363 goto fail; 14364 } 14365 } 14366 pos1 = semicolon1; 14367 } 14368 14369 /* We've made it out of that horrible O(m*n) construct and there are no 14370 * failures yet. We're not done yet, though, because params2 could have 14371 * an maddr, ttl, user, or method header and params1 did not. 14372 */ 14373 pos2 = params2; 14374 while (!ast_strlen_zero(pos2)) { 14375 char *name2 = pos2; 14376 char *value2 = strchr(pos2, '='); 14377 char *semicolon2 = strchr(pos2, ';'); 14378 if (semicolon2) { 14379 *semicolon2++ = '\0'; 14380 } 14381 if (!value2) { 14382 goto fail; 14383 } 14384 *value2++ = '\0'; 14385 if ((!strcasecmp(name2, "maddr") && !maddrmatch) || 14386 (!strcasecmp(name2, "ttl") && !ttlmatch) || 14387 (!strcasecmp(name2, "user") && !usermatch) || 14388 (!strcasecmp(name2, "method") && !methodmatch)) { 14389 goto fail; 14390 } 14391 } 14392 return 0; 14393 14394 fail: 14395 return 1; 14396 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 3798 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(), t38properties::direct, sip_pvt::flags, ast_frame::frametype, sip_pvt::initreq, INV_EARLY_MEDIA, sip_pvt::invitestate, sip_pvt::lastrtptx, sip_pvt::lock, ast_channel::nativeformats, sip_pvt::pendinginvite, ast_channel::readformat, sip_pvt::rtp, SIP_OUTGOING, SIP_PAGE2_T38SUPPORT, SIP_PROGRESS_SENT, t38properties::state, ast_frame::subclass, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_REINVITE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), transmit_reinvite_with_t38_sdp(), transmit_response_with_sdp(), sip_pvt::udptl, sip_pvt::vrtp, ast_channel::writeformat, and XMIT_UNRELIABLE.
03799 { 03800 struct sip_pvt *p = ast->tech_pvt; 03801 int res = 0; 03802 03803 switch (frame->frametype) { 03804 case AST_FRAME_VOICE: 03805 if (!(frame->subclass & ast->nativeformats)) { 03806 char s1[512], s2[512], s3[512]; 03807 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n", 03808 frame->subclass, 03809 ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK), 03810 ast->nativeformats & AST_FORMAT_AUDIO_MASK, 03811 ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat), 03812 ast->readformat, 03813 ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat), 03814 ast->writeformat); 03815 return 0; 03816 } 03817 if (p) { 03818 ast_mutex_lock(&p->lock); 03819 if (p->rtp) { 03820 /* If channel is not up, activate early media session */ 03821 if ((ast->_state != AST_STATE_UP) && 03822 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03823 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03824 ast_rtp_new_source(p->rtp); 03825 p->invitestate = INV_EARLY_MEDIA; 03826 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03827 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03828 } else if (p->t38.state == T38_ENABLED && !p->t38.direct) { 03829 p->t38.state = T38_DISABLED; 03830 transmit_reinvite_with_sdp(p); 03831 } else { 03832 p->lastrtptx = time(NULL); 03833 res = ast_rtp_write(p->rtp, frame); 03834 } 03835 } 03836 ast_mutex_unlock(&p->lock); 03837 } 03838 break; 03839 case AST_FRAME_VIDEO: 03840 if (p) { 03841 ast_mutex_lock(&p->lock); 03842 if (p->vrtp) { 03843 /* Activate video early media */ 03844 if ((ast->_state != AST_STATE_UP) && 03845 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03846 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03847 p->invitestate = INV_EARLY_MEDIA; 03848 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03849 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03850 } 03851 p->lastrtptx = time(NULL); 03852 res = ast_rtp_write(p->vrtp, frame); 03853 } 03854 ast_mutex_unlock(&p->lock); 03855 } 03856 break; 03857 case AST_FRAME_IMAGE: 03858 return 0; 03859 break; 03860 case AST_FRAME_MODEM: 03861 if (p) { 03862 ast_mutex_lock(&p->lock); 03863 /* UDPTL requires two-way communication, so early media is not needed here. 03864 we simply forget the frames if we get modem frames before the bridge is up. 03865 Fax will re-transmit. 03866 */ 03867 if (ast->_state == AST_STATE_UP) { 03868 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && p->t38.state == T38_DISABLED) { 03869 if (!p->pendinginvite) { 03870 p->t38.state = T38_LOCAL_REINVITE; 03871 transmit_reinvite_with_t38_sdp(p); 03872 } 03873 } else if (p->t38.state == T38_ENABLED) { 03874 res = ast_udptl_write(p->udptl, frame); 03875 } 03876 } 03877 ast_mutex_unlock(&p->lock); 03878 } 03879 break; 03880 default: 03881 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 03882 return 0; 03883 } 03884 03885 return res; 03886 }
static int sipsock_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Read data from SIP socket.
Definition at line 16452 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_PKT_DEBUG, sipsock, and transmit_response().
Referenced by do_monitor().
16453 { 16454 struct sip_request req; 16455 struct sockaddr_in sin = { 0, }; 16456 struct sip_pvt *p; 16457 int res; 16458 socklen_t len = sizeof(sin); 16459 int nounlock = 0; 16460 int recount = 0; 16461 int lockretry; 16462 16463 memset(&req, 0, sizeof(req)); 16464 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 16465 if (res < 0) { 16466 #if !defined(__FreeBSD__) 16467 if (errno == EAGAIN) 16468 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 16469 else 16470 #endif 16471 if (errno != ECONNREFUSED) 16472 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 16473 return 1; 16474 } 16475 if (option_debug && res == sizeof(req.data) - 1) 16476 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 16477 16478 req.data[res] = '\0'; 16479 req.len = res; 16480 if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */ 16481 ast_set_flag(&req, SIP_PKT_DEBUG); 16482 if (pedanticsipchecking) 16483 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 16484 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 16485 ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data); 16486 16487 if(parse_request(&req) == -1) /* Bad packet, can't parse */ 16488 return 1; 16489 16490 req.method = find_sip_method(req.rlPart1); 16491 16492 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 16493 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 16494 16495 if (req.headers < 2) /* Must have at least two headers */ 16496 return 1; 16497 16498 /* Process request, with netlock held, and with usual deadlock avoidance */ 16499 for (lockretry = 10; lockretry > 0; lockretry--) { 16500 ast_mutex_lock(&netlock); 16501 16502 /* Find the active SIP dialog or create a new one */ 16503 p = find_call(&req, &sin, req.method); /* returns p locked */ 16504 if (p == NULL) { 16505 if (option_debug) 16506 ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len); 16507 ast_mutex_unlock(&netlock); 16508 return 1; 16509 } 16510 /* Go ahead and lock the owner if it has one -- we may need it */ 16511 /* because this is deadlock-prone, we need to try and unlock if failed */ 16512 if (!p->owner || !ast_channel_trylock(p->owner)) 16513 break; /* locking succeeded */ 16514 if (lockretry != 1) { 16515 ast_mutex_unlock(&p->lock); 16516 ast_mutex_unlock(&netlock); 16517 /* Sleep for a very short amount of time */ 16518 usleep(1); 16519 } 16520 } 16521 p->recv = sin; 16522 16523 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */ 16524 append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2); 16525 16526 if (!lockretry) { 16527 if (!queue_request(p, &req)) { 16528 /* the request has been queued for later handling */ 16529 ast_mutex_unlock(&p->lock); 16530 ast_mutex_unlock(&netlock); 16531 return 1; 16532 } 16533 16534 /* This is unsafe, since p->owner is not locked. */ 16535 if (p->owner) 16536 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 ??? - ")); 16537 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 16538 if (req.method != SIP_ACK) 16539 transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */ 16540 /* XXX We could add retry-after to make sure they come back */ 16541 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 16542 ast_mutex_unlock(&p->lock); 16543 ast_mutex_unlock(&netlock); 16544 return 1; 16545 } 16546 16547 /* if there are queued requests on this sip_pvt, process them first, so that everything is 16548 handled in order 16549 */ 16550 if (!AST_LIST_EMPTY(&p->request_queue)) { 16551 AST_SCHED_DEL(sched, p->request_queue_sched_id); 16552 process_request_queue(p, &recount, &nounlock); 16553 } 16554 16555 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 16556 /* Request failed */ 16557 if (option_debug) 16558 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 16559 } 16560 16561 if (p->owner && !nounlock) 16562 ast_channel_unlock(p->owner); 16563 ast_mutex_unlock(&p->lock); 16564 ast_mutex_unlock(&netlock); 16565 if (recount) 16566 ast_update_use_count(); 16567 16568 return 1; 16569 }
static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 13187 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().
13188 { 13189 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 13190 if (p->rtp) 13191 ast_rtp_stop(p->rtp); 13192 if (p->vrtp) 13193 ast_rtp_stop(p->vrtp); 13194 if (p->udptl) 13195 ast_udptl_stop(p->udptl); 13196 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 11289 of file chan_sip.c.
References subscription_types, and type.
Referenced by sip_show_channel().
11290 { 11291 int i; 11292 11293 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 11294 if (subscription_types[i].type == subtype) { 11295 return subscription_types[i].text; 11296 } 11297 } 11298 return subscription_types[0].text; 11299 }
static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 6609 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_sdp().
06610 { 06611 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 06612 06613 if (maxrate & T38FAX_RATE_14400) { 06614 if (option_debug > 1) 06615 ast_log(LOG_DEBUG, "T38MaxBitRate 14400 found\n"); 06616 return 14400; 06617 } else if (maxrate & T38FAX_RATE_12000) { 06618 if (option_debug > 1) 06619 ast_log(LOG_DEBUG, "T38MaxBitRate 12000 found\n"); 06620 return 12000; 06621 } else if (maxrate & T38FAX_RATE_9600) { 06622 if (option_debug > 1) 06623 ast_log(LOG_DEBUG, "T38MaxBitRate 9600 found\n"); 06624 return 9600; 06625 } else if (maxrate & T38FAX_RATE_7200) { 06626 if (option_debug > 1) 06627 ast_log(LOG_DEBUG, "T38MaxBitRate 7200 found\n"); 06628 return 7200; 06629 } else if (maxrate & T38FAX_RATE_4800) { 06630 if (option_debug > 1) 06631 ast_log(LOG_DEBUG, "T38MaxBitRate 4800 found\n"); 06632 return 4800; 06633 } else if (maxrate & T38FAX_RATE_2400) { 06634 if (option_debug > 1) 06635 ast_log(LOG_DEBUG, "T38MaxBitRate 2400 found\n"); 06636 return 2400; 06637 } else { 06638 if (option_debug > 1) 06639 ast_log(LOG_DEBUG, "Strange, T38MaxBitRate NOT found in peers T38 SDP.\n"); 06640 return 0; 06641 } 06642 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 17625 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().
17626 { 17627 struct sip_peer *peer; 17628 17629 if (!(peer = ast_calloc(1, sizeof(*peer)))) 17630 return NULL; 17631 17632 apeerobjs++; 17633 ASTOBJ_INIT(peer); 17634 set_peer_defaults(peer); 17635 17636 ast_copy_string(peer->name, name, sizeof(peer->name)); 17637 17638 ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT); 17639 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 17640 peer->prefs = default_prefs; 17641 reg_source_db(peer); 17642 17643 return peer; 17644 }
static void temp_pvt_cleanup | ( | void * | ) | [static] |
Definition at line 6384 of file chan_sip.c.
References ast_string_field_free_memory, and free.
06385 { 06386 struct sip_pvt *p = data; 06387 06388 ast_string_field_free_memory(p); 06389 06390 free(data); 06391 }
static void temp_pvt_init | ( | void | ) | [static] |
static char * transfermode2str | ( | enum transfermodes | mode | ) | const [static] |
Convert transfer mode to text string.
Definition at line 10299 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().
10300 { 10301 if (mode == TRANSFER_OPENFORALL) 10302 return "open"; 10303 else if (mode == TRANSFER_CLOSED) 10304 return "closed"; 10305 return "strict"; 10306 }
static void transmit_fake_auth_response | ( | struct sip_pvt * | p, | |
int | sipmethod, | |||
struct sip_request * | req, | |||
enum xmittype | 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 9003 of file chan_sip.c.
References ast_dynamic_str_thread_get(), ast_dynamic_str_thread_set(), AST_DYNSTR_BUILD_FAILED, ast_skip_blanks(), ast_strlen_zero(), ast_test_flag, check_auth_buf, CHECK_AUTH_BUF_INITLEN, DEFAULT_TRANS_TIMEOUT, get_header(), sip_pvt::initreq, keys, sip_pvt::randdata, s, set_nonce_randdata(), SIP_PKT_IGNORE, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, ast_dynamic_str::str, transmit_response(), and transmit_response_with_auth().
Referenced by handle_request_invite(), handle_request_subscribe(), and register_verify().
09004 { 09005 /* We have to emulate EXACTLY what we'd get with a good peer 09006 * and a bad password, or else we leak information. */ 09007 const char *response = "407 Proxy Authentication Required"; 09008 const char *reqheader = "Proxy-Authorization"; 09009 const char *respheader = "Proxy-Authenticate"; 09010 const char *authtoken; 09011 struct ast_dynamic_str *buf; 09012 char *c; 09013 09014 /* table of recognised keywords, and their value in the digest */ 09015 enum keys { K_NONCE, K_LAST }; 09016 struct x { 09017 const char *key; 09018 const char *s; 09019 } *i, keys[] = { 09020 [K_NONCE] = { "nonce=", "" }, 09021 [K_LAST] = { NULL, NULL} 09022 }; 09023 09024 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 09025 response = "401 Unauthorized"; 09026 reqheader = "Authorization"; 09027 respheader = "WWW-Authenticate"; 09028 } 09029 authtoken = get_header(req, reqheader); 09030 if (ast_test_flag(req, SIP_PKT_IGNORE) && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 09031 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 09032 * information */ 09033 transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0); 09034 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 09035 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09036 return; 09037 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 09038 /* We have no auth, so issue challenge and request authentication */ 09039 set_nonce_randdata(p, 1); 09040 transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0); 09041 /* Schedule auto destroy in 32 seconds */ 09042 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09043 return; 09044 } 09045 09046 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) { 09047 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 09048 return; 09049 } 09050 09051 /* Make a copy of the response and parse it */ 09052 if (ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) { 09053 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 09054 return; 09055 } 09056 09057 c = buf->str; 09058 09059 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 09060 for (i = keys; i->key != NULL; i++) { 09061 const char *separator = ","; /* default */ 09062 09063 if (strncasecmp(c, i->key, strlen(i->key)) != 0) { 09064 continue; 09065 } 09066 /* Found. Skip keyword, take text in quotes or up to the separator. */ 09067 c += strlen(i->key); 09068 if (*c == '"') { /* in quotes. Skip first and look for last */ 09069 c++; 09070 separator = "\""; 09071 } 09072 i->s = c; 09073 strsep(&c, separator); 09074 break; 09075 } 09076 if (i->key == NULL) { /* not found, jump after space or comma */ 09077 strsep(&c, " ,"); 09078 } 09079 } 09080 09081 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 09082 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { 09083 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 09084 set_nonce_randdata(p, 1); 09085 } 09086 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 09087 09088 /* Schedule auto destroy in 32 seconds */ 09089 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09090 } else { 09091 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 09092 } 09093 }
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 8152 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
08153 { 08154 struct sip_request req; 08155 08156 reqprep(&req, p, SIP_INFO, 0, 1); 08157 add_digit(&req, digit, duration); 08158 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08159 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 8162 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
08163 { 08164 struct sip_request req; 08165 08166 reqprep(&req, p, SIP_INFO, 0, 1); 08167 add_vidupdate(&req); 08168 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08169 }
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 7386 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_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_REINVITE, sip_pvt::udptl, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.
Referenced by do_proxy_auth(), sip_call(), and sip_poke_peer().
07387 { 07388 struct sip_request req; 07389 07390 req.method = sipmethod; 07391 if (init) { /* Seems like init always is 2 */ 07392 /* Bump branch even on initial requests */ 07393 p->branch ^= ast_random(); 07394 p->invite_branch = p->branch; 07395 build_via(p); 07396 if (init > 1) 07397 initreqprep(&req, p, sipmethod); 07398 else 07399 reqprep(&req, p, sipmethod, 0, 0); 07400 } else 07401 reqprep(&req, p, sipmethod, 0, 1); 07402 07403 if (p->options && p->options->auth) 07404 add_header(&req, p->options->authheader, p->options->auth); 07405 append_date(&req); 07406 if (sipmethod == SIP_REFER) { /* Call transfer */ 07407 if (p->refer) { 07408 char buf[SIPBUFSIZE]; 07409 if (!ast_strlen_zero(p->refer->refer_to)) 07410 add_header(&req, "Refer-To", p->refer->refer_to); 07411 if (!ast_strlen_zero(p->refer->referred_by)) { 07412 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 07413 add_header(&req, "Referred-By", buf); 07414 } 07415 } 07416 } 07417 /* This new INVITE is part of an attended transfer. Make sure that the 07418 other end knows and replace the current call with this new call */ 07419 if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) { 07420 add_header(&req, "Replaces", p->options->replaces); 07421 add_header(&req, "Require", "replaces"); 07422 } 07423 07424 add_header(&req, "Allow", ALLOWED_METHODS); 07425 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07426 if (p->options && p->options->addsipheaders && p->owner) { 07427 struct ast_channel *chan = p->owner; /* The owner channel */ 07428 struct varshead *headp; 07429 07430 ast_channel_lock(chan); 07431 07432 headp = &chan->varshead; 07433 07434 if (!headp) 07435 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 07436 else { 07437 const struct ast_var_t *current; 07438 AST_LIST_TRAVERSE(headp, current, entries) { 07439 /* SIPADDHEADER: Add SIP header to outgoing call */ 07440 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 07441 char *content, *end; 07442 const char *header = ast_var_value(current); 07443 char *headdup = ast_strdupa(header); 07444 07445 /* Strip of the starting " (if it's there) */ 07446 if (*headdup == '"') 07447 headdup++; 07448 if ((content = strchr(headdup, ':'))) { 07449 *content++ = '\0'; 07450 content = ast_skip_blanks(content); /* Skip white space */ 07451 /* Strip the ending " (if it's there) */ 07452 end = content + strlen(content) -1; 07453 if (*end == '"') 07454 *end = '\0'; 07455 07456 add_header(&req, headdup, content); 07457 if (sipdebug) 07458 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 07459 } 07460 } 07461 } 07462 } 07463 07464 ast_channel_unlock(chan); 07465 } 07466 if (sdp) { 07467 if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) { 07468 ast_udptl_offered_from_local(p->udptl, 1); 07469 if (option_debug) 07470 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 07471 add_sdp(&req, p, 0, 1); 07472 } else if (p->rtp) 07473 add_sdp(&req, p, 1, 0); 07474 } else { 07475 add_header_contentLength(&req, 0); 07476 } 07477 07478 if (!p->initreq.headers || init > 2) 07479 initialize_initreq(p, &req); 07480 p->lastinvite = p->ocseq; 07481 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 07482 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 8061 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().
08062 { 08063 struct sip_request req; 08064 08065 reqprep(&req, p, SIP_MESSAGE, 0, 1); 08066 add_text(&req, text); 08067 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08068 }
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 7673 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_strlen_zero(), 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, ourport, S_OR, send_request(), SIP_NOTIFY, SIP_PAGE2_BUGGY_MWI, STANDARD_SIP_PORT, sip_pvt::subscribed, t, and XMIT_RELIABLE.
Referenced by sip_send_mwi_to_peer().
07674 { 07675 struct sip_request req; 07676 char tmp[500]; 07677 char *t = tmp; 07678 size_t maxbytes = sizeof(tmp); 07679 07680 initreqprep(&req, p, SIP_NOTIFY); 07681 add_header(&req, "Event", "message-summary"); 07682 add_header(&req, "Content-Type", default_notifymime); 07683 07684 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 07685 /* if we listen to non-standard SIP port we have to specify the SIP port 07686 in the URI, except domains are used - in this case the SRV records should be 07687 used to redirect the client to the non-standard SIP port */ 07688 if ((ourport != STANDARD_SIP_PORT) && ast_strlen_zero(p->fromdomain)) { 07689 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s:%d\r\n", 07690 S_OR(vmexten, default_vmexten), ast_inet_ntoa(p->ourip), ourport); 07691 } else { 07692 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 07693 S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 07694 } 07695 /* Cisco has a bug in the SIP stack where it can't accept the 07696 (0/0) notification. This can temporarily be disabled in 07697 sip.conf with the "buggymwi" option */ 07698 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)")); 07699 07700 if (p->subscribed) { 07701 if (p->expiry) 07702 add_header(&req, "Subscription-State", "active"); 07703 else /* Expired */ 07704 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07705 } 07706 07707 if (t > tmp + sizeof(tmp)) 07708 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07709 07710 add_header_contentLength(&req, strlen(tmp)); 07711 add_line(&req, tmp); 07712 07713 if (!p->initreq.headers) 07714 initialize_initreq(p, &req); 07715 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07716 }
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 7727 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ALLOWED_METHODS, sip_request::headers, initialize_initreq(), sip_pvt::initreq, sip_pvt::ocseq, reqprep(), send_request(), SIP_NOTIFY, SIPBUFSIZE, SUPPORTED_EXTENSIONS, and XMIT_RELIABLE.
Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().
07728 { 07729 struct sip_request req; 07730 char tmp[SIPBUFSIZE/2]; 07731 07732 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07733 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 07734 add_header(&req, "Event", tmp); 07735 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 07736 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 07737 add_header(&req, "Allow", ALLOWED_METHODS); 07738 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07739 07740 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 07741 add_header_contentLength(&req, strlen(tmp)); 07742 add_line(&req, tmp); 07743 07744 if (!p->initreq.headers) 07745 initialize_initreq(p, &req); 07746 07747 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07748 }
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 8082 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().
08083 { 08084 struct sip_request req = { 08085 .headers = 0, 08086 }; 08087 char from[256]; 08088 const char *of; 08089 char *c; 08090 char referto[256]; 08091 char *ttag, *ftag; 08092 char *theirtag = ast_strdupa(p->theirtag); 08093 08094 if (option_debug || sipdebug) 08095 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 08096 08097 /* Are we transfering an inbound or outbound call ? */ 08098 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 08099 of = get_header(&p->initreq, "To"); 08100 ttag = theirtag; 08101 ftag = p->tag; 08102 } else { 08103 of = get_header(&p->initreq, "From"); 08104 ftag = theirtag; 08105 ttag = p->tag; 08106 } 08107 08108 ast_copy_string(from, of, sizeof(from)); 08109 of = get_in_brackets(from); 08110 ast_string_field_set(p, from, of); 08111 if (strncasecmp(of, "sip:", 4)) 08112 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 08113 else 08114 of += 4; 08115 /* Get just the username part */ 08116 if ((c = strchr(dest, '@'))) 08117 c = NULL; 08118 else if ((c = strchr(of, '@'))) 08119 *c++ = '\0'; 08120 if (c) 08121 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 08122 else 08123 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 08124 08125 /* save in case we get 407 challenge */ 08126 sip_refer_allocate(p); 08127 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 08128 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 08129 p->refer->status = REFER_SENT; /* Set refer status */ 08130 08131 reqprep(&req, p, SIP_REFER, 0, 1); 08132 08133 add_header(&req, "Refer-To", referto); 08134 add_header(&req, "Allow", ALLOWED_METHODS); 08135 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 08136 if (!ast_strlen_zero(p->our_contact)) 08137 add_header(&req, "Referred-By", p->our_contact); 08138 08139 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08140 /* We should propably wait for a NOTIFY here until we ack the transfer */ 08141 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 08142 08143 /*! \todo In theory, we should hang around and wait for a reply, before 08144 returning to the dial plan here. Don't know really how that would 08145 affect the transfer() app or the pbx, but, well, to make this 08146 useful we should have a STATUS code on transfer(). 08147 */ 08148 }
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 7853 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, FALSE, 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_registry::needdns, 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, sip_registry::us, username, sip_registry::username, sip_pvt::via, and XMIT_CRITICAL.
Referenced by __sip_do_register(), do_register_auth(), and sip_reg_timeout().
07854 { 07855 struct sip_request req; 07856 char from[256]; 07857 char to[256]; 07858 char tmp[80]; 07859 char addr[80]; 07860 struct sip_pvt *p; 07861 char *fromdomain; 07862 07863 /* exit if we are already in process with this registrar ?*/ 07864 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 07865 if (r) { 07866 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 07867 } 07868 return 0; 07869 } 07870 07871 if (r->call) { /* We have a registration */ 07872 if (!auth) { 07873 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 07874 return 0; 07875 } else { 07876 p = r->call; 07877 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 07878 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 07879 } 07880 } else { 07881 /* Build callid for registration if we haven't registered before */ 07882 if (!r->callid_valid) { 07883 build_callid_registry(r, __ourip, default_fromdomain); 07884 r->callid_valid = TRUE; 07885 } 07886 /* Allocate SIP packet for registration */ 07887 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) { 07888 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 07889 return 0; 07890 } 07891 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07892 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 07893 /* Find address to hostname if we haven't tried to connect 07894 * or a connection error has occurred */ 07895 if (create_addr(p, r->hostname, r->needdns ? NULL : &r->us)) { 07896 /* we have what we hope is a temporary network error, 07897 * probably DNS. We need to reschedule a registration try */ 07898 sip_destroy(p); 07899 07900 if (r->timeout > -1) 07901 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 07902 else 07903 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); 07904 07905 AST_SCHED_DEL(sched, r->timeout); 07906 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07907 r->regattempts++; 07908 return 0; 07909 } 07910 if (r->needdns) { 07911 memcpy(&r->us, &p->sa, sizeof(r->us)); 07912 } 07913 r->needdns = FALSE; 07914 /* Copy back Call-ID in case create_addr changed it */ 07915 ast_string_field_set(r, callid, p->callid); 07916 if (r->portno) { 07917 p->sa.sin_port = htons(r->portno); 07918 p->recv.sin_port = htons(r->portno); 07919 } else /* Set registry port to the port set from the peer definition/srv or default */ 07920 r->portno = ntohs(p->sa.sin_port); 07921 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 07922 r->call=p; /* Save pointer to SIP packet */ 07923 p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ 07924 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 07925 ast_string_field_set(p, peersecret, r->secret); 07926 if (!ast_strlen_zero(r->md5secret)) 07927 ast_string_field_set(p, peermd5secret, r->md5secret); 07928 /* User name in this realm 07929 - if authuser is set, use that, otherwise use username */ 07930 if (!ast_strlen_zero(r->authuser)) { 07931 ast_string_field_set(p, peername, r->authuser); 07932 ast_string_field_set(p, authname, r->authuser); 07933 } else if (!ast_strlen_zero(r->username)) { 07934 ast_string_field_set(p, peername, r->username); 07935 ast_string_field_set(p, authname, r->username); 07936 ast_string_field_set(p, fromuser, r->username); 07937 } 07938 if (!ast_strlen_zero(r->username)) 07939 ast_string_field_set(p, username, r->username); 07940 /* Save extension in packet */ 07941 ast_string_field_set(p, exten, r->contact); 07942 07943 /* 07944 check which address we should use in our contact header 07945 based on whether the remote host is on the external or 07946 internal network so we can register through nat 07947 */ 07948 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 07949 p->ourip = bindaddr.sin_addr; 07950 build_contact(p); 07951 } 07952 07953 /* set up a timeout */ 07954 if (auth == NULL) { 07955 if (r->timeout > -1) 07956 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 07957 AST_SCHED_DEL(sched, r->timeout); 07958 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07959 if (option_debug) 07960 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 07961 } 07962 07963 if ((fromdomain = strchr(r->username, '@'))) { 07964 /* the domain name is just behind '@' */ 07965 fromdomain++ ; 07966 /* We have a domain in the username for registration */ 07967 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 07968 if (!ast_strlen_zero(p->theirtag)) 07969 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 07970 else 07971 snprintf(to, sizeof(to), "<sip:%s>", r->username); 07972 07973 /* If the registration username contains '@', then the domain should be used as 07974 the equivalent of "fromdomain" for the registration */ 07975 if (ast_strlen_zero(p->fromdomain)) { 07976 ast_string_field_set(p, fromdomain, fromdomain); 07977 } 07978 } else { 07979 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 07980 if (!ast_strlen_zero(p->theirtag)) 07981 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 07982 else 07983 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 07984 } 07985 07986 /* Fromdomain is what we are registering to, regardless of actual 07987 host name from SRV */ 07988 if (!ast_strlen_zero(p->fromdomain)) { 07989 if (r->portno && r->portno != STANDARD_SIP_PORT) 07990 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 07991 else 07992 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 07993 } else { 07994 if (r->portno && r->portno != STANDARD_SIP_PORT) 07995 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 07996 else 07997 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 07998 } 07999 ast_string_field_set(p, uri, addr); 08000 08001 p->branch ^= ast_random(); 08002 08003 init_req(&req, sipmethod, addr); 08004 08005 /* Add to CSEQ */ 08006 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 08007 p->ocseq = r->ocseq; 08008 08009 build_via(p); 08010 add_header(&req, "Via", p->via); 08011 add_header(&req, "From", from); 08012 add_header(&req, "To", to); 08013 add_header(&req, "Call-ID", p->callid); 08014 add_header(&req, "CSeq", tmp); 08015 if (!ast_strlen_zero(global_useragent)) 08016 add_header(&req, "User-Agent", global_useragent); 08017 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 08018 08019 08020 if (auth) /* Add auth header */ 08021 add_header(&req, authheader, auth); 08022 else if (!ast_strlen_zero(r->nonce)) { 08023 char digest[1024]; 08024 08025 /* We have auth data to reuse, build a digest header! */ 08026 if (sipdebug) 08027 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 08028 ast_string_field_set(p, realm, r->realm); 08029 ast_string_field_set(p, nonce, r->nonce); 08030 ast_string_field_set(p, domain, r->domain); 08031 ast_string_field_set(p, opaque, r->opaque); 08032 ast_string_field_set(p, qop, r->qop); 08033 r->noncecount++; 08034 p->noncecount = r->noncecount; 08035 08036 memset(digest,0,sizeof(digest)); 08037 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 08038 add_header(&req, "Authorization", digest); 08039 else 08040 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 08041 08042 } 08043 08044 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 08045 add_header(&req, "Expires", tmp); 08046 add_header(&req, "Contact", p->our_contact); 08047 add_header(&req, "Event", "registration"); 08048 add_header_contentLength(&req, 0); 08049 08050 initialize_initreq(p, &req); 08051 if (sip_debug_test_pvt(p)) 08052 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 08053 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 08054 r->regattempts++; /* Another attempt */ 08055 if (option_debug > 3) 08056 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 08057 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 08058 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with SDP.
Definition at line 7103 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(), sip_set_rtp_peer(), and sip_write().
07104 { 07105 struct sip_request req; 07106 07107 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 07108 07109 add_header(&req, "Allow", ALLOWED_METHODS); 07110 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07111 if (sipdebug) 07112 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 07113 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07114 append_history(p, "ReInv", "Re-invite sent"); 07115 add_sdp(&req, p, 1, 0); 07116 /* Use this as the basis */ 07117 initialize_initreq(p, &req); 07118 p->lastinvite = p->ocseq; 07119 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 07120 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07121 }
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 7127 of file chan_sip.c.
References add_header(), add_sdp(), ALLOWED_METHODS, ast_set_flag, ast_test_flag, 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, and XMIT_CRITICAL.
Referenced by sip_handle_t38_reinvite(), sip_read(), sip_set_udptl_peer(), and sip_write().
07128 { 07129 struct sip_request req; 07130 07131 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 07132 07133 add_header(&req, "Allow", ALLOWED_METHODS); 07134 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07135 if (sipdebug) 07136 add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)"); 07137 add_sdp(&req, p, 0, 1); 07138 07139 /* Use this as the basis */ 07140 initialize_initreq(p, &req); 07141 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 07142 p->lastinvite = p->ocseq; 07143 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07144 }
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 8174 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().
08175 { 08176 struct sip_request resp; 08177 08178 if (sipmethod == SIP_ACK) 08179 p->invitestate = INV_CONFIRMED; 08180 08181 reqprep(&resp, p, sipmethod, seqno, newbranch); 08182 add_header_contentLength(&resp, 0); 08183 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 08184 }
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 8187 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, sip_pvt::hangupcause, sip_pvt::ocseq, sip_pvt::options, PROXY_AUTH, sip_pvt::realm, reqprep(), send_request(), SIP_BYE, and WWW_AUTH.
Referenced by __sip_autodestruct(), check_pendings(), and sip_hangup().
08188 { 08189 struct sip_request resp; 08190 08191 reqprep(&resp, p, sipmethod, seqno, newbranch); 08192 if (!ast_strlen_zero(p->realm)) { 08193 char digest[1024]; 08194 08195 memset(digest, 0, sizeof(digest)); 08196 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 08197 if (p->options && p->options->auth_type == PROXY_AUTH) 08198 add_header(&resp, "Proxy-Authorization", digest); 08199 else if (p->options && p->options->auth_type == WWW_AUTH) 08200 add_header(&resp, "Authorization", digest); 08201 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 08202 add_header(&resp, "Proxy-Authorization", digest); 08203 } else 08204 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 08205 } 08206 /* If we are hanging up and know a cause for that, send it in clear text to make 08207 debugging easier. */ 08208 if (sipmethod == SIP_BYE) { 08209 char buf[10]; 08210 08211 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->hangupcause)); 08212 snprintf(buf, sizeof(buf), "%d", p->hangupcause); 08213 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 08214 } 08215 08216 add_header_contentLength(&resp, 0); 08217 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 08218 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 6445 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
06446 { 06447 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06448 }
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 6464 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().
06465 { 06466 return __transmit_response(p, msg, req, XMIT_CRITICAL); 06467 }
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 6394 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.
06395 { 06396 struct sip_pvt *p = NULL; 06397 06398 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 06399 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 06400 return -1; 06401 } 06402 06403 /* if the structure was just allocated, initialize it */ 06404 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 06405 ast_set_flag(&p->flags[0], SIP_NO_HISTORY); 06406 if (ast_string_field_init(p, 512)) 06407 return -1; 06408 } 06409 06410 /* Initialize the bare minimum */ 06411 p->method = intended_method; 06412 06413 if (sin) { 06414 p->sa = *sin; 06415 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 06416 p->ourip = __ourip; 06417 } else 06418 p->ourip = __ourip; 06419 06420 p->branch = ast_random(); 06421 make_our_tag(p->tag, sizeof(p->tag)); 06422 p->ocseq = INITIAL_CSEQ; 06423 06424 if (useglobal_nat && sin) { 06425 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 06426 p->recv = *sin; 06427 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 06428 } 06429 check_via(p, req); 06430 06431 ast_string_field_set(p, fromdomain, default_fromdomain); 06432 build_via(p); 06433 ast_string_field_set(p, callid, callid); 06434 06435 /* Use this temporary pvt structure to send the message */ 06436 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06437 06438 /* Free the string fields, but not the pool space */ 06439 ast_string_field_reset_all(p); 06440 06441 return 0; 06442 }
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 6492 of file chan_sip.c.
References add_header(), add_header_contentLength(), respprep(), and send_response().
Referenced by handle_request(), and handle_request_options().
06493 { 06494 struct sip_request resp; 06495 respprep(&resp, p, msg, req); 06496 add_header(&resp, "Accept", "application/sdp"); 06497 add_header_contentLength(&resp, 0); 06498 return send_response(p, &resp, reliable, 0); 06499 }
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 6502 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().
06503 { 06504 struct sip_request resp; 06505 char tmp[512]; 06506 int seqno = 0; 06507 06508 if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) { 06509 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06510 return -1; 06511 } 06512 /* Stale means that they sent us correct authentication, but 06513 based it on an old challenge (nonce) */ 06514 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 06515 respprep(&resp, p, msg, req); 06516 add_header(&resp, header, tmp); 06517 add_header_contentLength(&resp, 0); 06518 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 06519 return send_response(p, &resp, reliable, seqno); 06520 }
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 6482 of file chan_sip.c.
References add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
06483 { 06484 struct sip_request resp; 06485 respprep(&resp, p, msg, req); 06486 append_date(&resp); 06487 add_header_contentLength(&resp, 0); 06488 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06489 }
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 7027 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, t38properties::state, sip_pvt::t38, T38_ENABLED, T38_PEER_DIRECT, and try_suggested_sip_codec().
Referenced by handle_invite_replaces(), handle_request_invite(), sip_answer(), sip_indicate(), and sip_write().
07028 { 07029 struct sip_request resp; 07030 int seqno; 07031 if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) { 07032 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 07033 return -1; 07034 } 07035 respprep(&resp, p, msg, req); 07036 if (p->rtp) { 07037 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07038 if (option_debug) 07039 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 07040 ast_rtp_codec_setpref(p->rtp, &p->prefs); 07041 } 07042 try_suggested_sip_codec(p); 07043 if (p->t38.state == T38_PEER_DIRECT || p->t38.state == T38_ENABLED) { 07044 p->t38.state = T38_ENABLED; 07045 add_sdp(&resp, p, 1, 1); 07046 } else { 07047 add_sdp(&resp, p, 1, 0); 07048 } 07049 } else 07050 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 07051 if (reliable && !p->pendinginvite) 07052 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 07053 return send_response(p, &resp, reliable, seqno); 07054 }
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 6988 of file chan_sip.c.
References add_sdp(), ast_log(), sip_pvt::callid, get_header(), LOG_ERROR, sip_pvt::pendinginvite, respprep(), send_response(), and sip_pvt::udptl.
Referenced by handle_request_invite(), and sip_handle_t38_reinvite().
06989 { 06990 struct sip_request resp; 06991 int seqno; 06992 06993 if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) { 06994 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06995 return -1; 06996 } 06997 respprep(&resp, p, msg, req); 06998 if (p->udptl) { 06999 add_sdp(&resp, p, 0, 1); 07000 } else 07001 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 07002 if (retrans && !p->pendinginvite) 07003 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 07004 return send_response(p, &resp, retrans, seqno); 07005 }
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 6451 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
06452 { 06453 struct sip_request resp; 06454 respprep(&resp, p, msg, req); 06455 append_date(&resp); 06456 add_header(&resp, "Unsupported", unsupported); 06457 add_header_contentLength(&resp, 0); 06458 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06459 }
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 7719 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().
07720 { 07721 if (!p->initreq.headers) /* Initialize first request before sending */ 07722 initialize_initreq(p, req); 07723 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 07724 }
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 7485 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().
07486 { 07487 char tmp[4000], from[256], to[256]; 07488 char *t = tmp, *c, *mfrom, *mto; 07489 size_t maxbytes = sizeof(tmp); 07490 struct sip_request req; 07491 char hint[AST_MAX_EXTENSION]; 07492 char *statestring = "terminated"; 07493 const struct cfsubscription_types *subscriptiontype; 07494 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 07495 char *pidfstate = "--"; 07496 char *pidfnote= "Ready"; 07497 07498 memset(from, 0, sizeof(from)); 07499 memset(to, 0, sizeof(to)); 07500 memset(tmp, 0, sizeof(tmp)); 07501 07502 switch (state) { 07503 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 07504 statestring = (global_notifyringing) ? "early" : "confirmed"; 07505 local_state = NOTIFY_INUSE; 07506 pidfstate = "busy"; 07507 pidfnote = "Ringing"; 07508 break; 07509 case AST_EXTENSION_RINGING: 07510 statestring = "early"; 07511 local_state = NOTIFY_INUSE; 07512 pidfstate = "busy"; 07513 pidfnote = "Ringing"; 07514 break; 07515 case AST_EXTENSION_INUSE: 07516 statestring = "confirmed"; 07517 local_state = NOTIFY_INUSE; 07518 pidfstate = "busy"; 07519 pidfnote = "On the phone"; 07520 break; 07521 case AST_EXTENSION_BUSY: 07522 statestring = "confirmed"; 07523 local_state = NOTIFY_CLOSED; 07524 pidfstate = "busy"; 07525 pidfnote = "On the phone"; 07526 break; 07527 case AST_EXTENSION_UNAVAILABLE: 07528 statestring = "terminated"; 07529 local_state = NOTIFY_CLOSED; 07530 pidfstate = "away"; 07531 pidfnote = "Unavailable"; 07532 break; 07533 case AST_EXTENSION_ONHOLD: 07534 statestring = "confirmed"; 07535 local_state = NOTIFY_CLOSED; 07536 pidfstate = "busy"; 07537 pidfnote = "On Hold"; 07538 break; 07539 case AST_EXTENSION_NOT_INUSE: 07540 default: 07541 /* Default setting */ 07542 break; 07543 } 07544 07545 subscriptiontype = find_subscription_type(p->subscribed); 07546 07547 /* Check which device/devices we are watching and if they are registered */ 07548 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 07549 char *hint2 = hint, *individual_hint = NULL; 07550 int hint_count = 0, unavailable_count = 0; 07551 07552 while ((individual_hint = strsep(&hint2, "&"))) { 07553 hint_count++; 07554 07555 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 07556 unavailable_count++; 07557 } 07558 07559 /* If none of the hinted devices are registered, we will 07560 * override notification and show no availability. 07561 */ 07562 if (hint_count > 0 && hint_count == unavailable_count) { 07563 local_state = NOTIFY_CLOSED; 07564 pidfstate = "away"; 07565 pidfnote = "Not online"; 07566 } 07567 } 07568 07569 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 07570 c = get_in_brackets(from); 07571 if (strncasecmp(c, "sip:", 4)) { 07572 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07573 return -1; 07574 } 07575 mfrom = strsep(&c, ";"); /* trim ; and beyond */ 07576 07577 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 07578 c = get_in_brackets(to); 07579 if (strncasecmp(c, "sip:", 4)) { 07580 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07581 return -1; 07582 } 07583 mto = strsep(&c, ";"); /* trim ; and beyond */ 07584 07585 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07586 07587 07588 add_header(&req, "Event", subscriptiontype->event); 07589 add_header(&req, "Content-Type", subscriptiontype->mediatype); 07590 switch(state) { 07591 case AST_EXTENSION_DEACTIVATED: 07592 if (timeout) 07593 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07594 else { 07595 add_header(&req, "Subscription-State", "terminated;reason=probation"); 07596 add_header(&req, "Retry-After", "60"); 07597 } 07598 break; 07599 case AST_EXTENSION_REMOVED: 07600 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 07601 break; 07602 default: 07603 if (p->expiry) 07604 add_header(&req, "Subscription-State", "active"); 07605 else /* Expired */ 07606 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07607 } 07608 switch (p->subscribed) { 07609 case XPIDF_XML: 07610 case CPIM_PIDF_XML: 07611 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07612 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 07613 ast_build_string(&t, &maxbytes, "<presence>\n"); 07614 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 07615 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 07616 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 07617 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 07618 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 07619 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 07620 break; 07621 case PIDF_XML: /* Eyebeam supports this format */ 07622 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 07623 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); 07624 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 07625 if (pidfstate[0] != '-') 07626 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 07627 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 07628 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 07629 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 07630 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 07631 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 07632 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 07633 else 07634 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 07635 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 07636 break; 07637 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 07638 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07639 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); 07640 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 07641 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 07642 else 07643 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 07644 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 07645 if (state == AST_EXTENSION_ONHOLD) { 07646 ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n" 07647 "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n" 07648 "</target>\n</local>\n", mto); 07649 } 07650 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 07651 break; 07652 case NONE: 07653 default: 07654 break; 07655 } 07656 07657 if (t > tmp + sizeof(tmp)) 07658 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07659 07660 add_header_contentLength(&req, strlen(tmp)); 07661 add_line(&req, tmp); 07662 p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */ 07663 07664 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07665 }
static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 3741 of file chan_sip.c.
References ast_channel_trylock, ast_channel_unlock, ast_getformatbyname(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_strdupa, ast_strlen_zero(), sip_pvt::capability, sip_pvt::jointcapability, sip_pvt::lock, LOG_NOTICE, sip_pvt::owner, pbx_builtin_getvar_helper(), and S_OR.
Referenced by sip_answer(), and transmit_response_with_sdp().
03742 { 03743 int fmt; 03744 const char *codec; 03745 03746 while (p->owner && ast_channel_trylock(p->owner)) { 03747 ast_mutex_unlock(&p->lock); 03748 sched_yield(); 03749 ast_mutex_lock(&p->lock); 03750 } 03751 03752 if (!p->owner) 03753 return; 03754 03755 codec = ast_strdupa(S_OR(pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"), "")); 03756 03757 ast_channel_unlock(p->owner); 03758 03759 if (ast_strlen_zero(codec)) 03760 return; 03761 03762 fmt = ast_getformatbyname(codec); 03763 if (fmt) { 03764 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 03765 if (p->jointcapability & fmt) { 03766 p->jointcapability &= fmt; 03767 p->capability &= fmt; 03768 } else 03769 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 03770 } else 03771 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 03772 return; 03773 }
static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 19260 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, TRUE, and userl.
19261 { 19262 struct sip_pvt *p, *pl; 19263 19264 /* First, take us out of the channel type list */ 19265 ast_channel_unregister(&sip_tech); 19266 19267 /* Unregister dial plan functions */ 19268 ast_custom_function_unregister(&sipchaninfo_function); 19269 ast_custom_function_unregister(&sippeer_function); 19270 ast_custom_function_unregister(&sip_header_function); 19271 ast_custom_function_unregister(&checksipdomain_function); 19272 19273 /* Unregister dial plan applications */ 19274 ast_unregister_application(app_dtmfmode); 19275 ast_unregister_application(app_sipaddheader); 19276 19277 /* Unregister CLI commands */ 19278 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 19279 19280 /* Disconnect from the RTP subsystem */ 19281 ast_rtp_proto_unregister(&sip_rtp); 19282 19283 /* Disconnect from UDPTL */ 19284 ast_udptl_proto_unregister(&sip_udptl); 19285 19286 /* Unregister AMI actions */ 19287 ast_manager_unregister("SIPpeers"); 19288 ast_manager_unregister("SIPshowpeer"); 19289 19290 ast_mutex_lock(&iflock); 19291 /* Hangup all interfaces if they have an owner */ 19292 for (p = iflist; p ; p = p->next) { 19293 if (p->owner) 19294 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 19295 } 19296 ast_mutex_unlock(&iflock); 19297 19298 ast_mutex_lock(&monlock); 19299 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 19300 pthread_cancel(monitor_thread); 19301 pthread_kill(monitor_thread, SIGURG); 19302 pthread_join(monitor_thread, NULL); 19303 } 19304 monitor_thread = AST_PTHREADT_STOP; 19305 ast_mutex_unlock(&monlock); 19306 19307 restartdestroy: 19308 ast_mutex_lock(&iflock); 19309 /* Destroy all the interfaces and free their memory */ 19310 p = iflist; 19311 while (p) { 19312 pl = p; 19313 p = p->next; 19314 if (__sip_destroy(pl, TRUE) < 0) { 19315 /* Something is still bridged, let it react to getting a hangup */ 19316 iflist = p; 19317 ast_mutex_unlock(&iflock); 19318 usleep(1); 19319 goto restartdestroy; 19320 } 19321 } 19322 iflist = NULL; 19323 ast_mutex_unlock(&iflock); 19324 19325 /* Free memory for local network address mask */ 19326 ast_free_ha(localaddr); 19327 19328 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 19329 ASTOBJ_CONTAINER_DESTROY(&userl); 19330 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 19331 ASTOBJ_CONTAINER_DESTROY(&peerl); 19332 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 19333 ASTOBJ_CONTAINER_DESTROY(®l); 19334 19335 clear_realm_authentication(authl); 19336 clear_sip_domains(); 19337 close(sipsock); 19338 sched_context_destroy(sched); 19339 19340 return 0; 19341 }
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 3290 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().
03291 { 03292 char name[256]; 03293 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 03294 int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL); 03295 struct sip_user *u = NULL; 03296 struct sip_peer *p = NULL; 03297 03298 if (option_debug > 2) 03299 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 03300 03301 /* Test if we need to check call limits, in order to avoid 03302 realtime lookups if we do not need it */ 03303 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 03304 return 0; 03305 03306 ast_copy_string(name, fup->username, sizeof(name)); 03307 03308 /* Check the list of users only for incoming calls */ 03309 if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) { 03310 inuse = &u->inUse; 03311 call_limit = &u->call_limit; 03312 inringing = NULL; 03313 } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1, 0) ) ) { /* Try to find peer */ 03314 inuse = &p->inUse; 03315 call_limit = &p->call_limit; 03316 inringing = &p->inRinging; 03317 ast_copy_string(name, fup->peername, sizeof(name)); 03318 } 03319 if (!p && !u) { 03320 if (option_debug > 1) 03321 ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name); 03322 return 0; 03323 } 03324 03325 switch(event) { 03326 /* incoming and outgoing affects the inUse counter */ 03327 case DEC_CALL_LIMIT: 03328 if ( *inuse > 0 ) { 03329 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 03330 (*inuse)--; 03331 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 03332 } 03333 } else { 03334 *inuse = 0; 03335 } 03336 if (inringing) { 03337 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03338 if (*inringing > 0) 03339 (*inringing)--; 03340 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03341 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername); 03342 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03343 } 03344 } 03345 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) { 03346 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 03347 sip_peer_hold(fup, 0); 03348 } 03349 if (option_debug > 1 || sipdebug) { 03350 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 03351 } 03352 break; 03353 03354 case INC_CALL_RINGING: 03355 case INC_CALL_LIMIT: 03356 if (*call_limit > 0 ) { 03357 /* Let call limit affect only outgoing calls */ 03358 if (outgoing && (*inuse >= *call_limit)) { 03359 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); 03360 if (u) 03361 ASTOBJ_UNREF(u, sip_destroy_user); 03362 else 03363 ASTOBJ_UNREF(p, sip_destroy_peer); 03364 return -1; 03365 } 03366 } 03367 if (inringing && (event == INC_CALL_RINGING)) { 03368 if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03369 (*inringing)++; 03370 ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03371 } 03372 } 03373 /* Continue */ 03374 (*inuse)++; 03375 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 03376 if (option_debug > 1 || sipdebug) { 03377 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 03378 } 03379 break; 03380 03381 case DEC_CALL_RINGING: 03382 if (inringing) { 03383 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03384 if (*inringing > 0) 03385 (*inringing)--; 03386 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03387 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name); 03388 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03389 } 03390 } 03391 break; 03392 03393 default: 03394 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 03395 } 03396 if (p) { 03397 ast_device_state_changed("SIP/%s", p->name); 03398 ASTOBJ_UNREF(p, sip_destroy_peer); 03399 } else /* u must be set */ 03400 ASTOBJ_UNREF(u, sip_destroy_user); 03401 return 0; 03402 }
static void update_peer | ( | struct sip_peer * | p, | |
int | expiry | |||
) | [static] |
Update peer data in database (if used).
Definition at line 2548 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, sip_peer::fullcontact, global_flags, sip_peer::lastms, sip_peer::name, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_REALTIME, and sip_peer::username.
Referenced by register_verify().
02549 { 02550 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02551 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) && 02552 (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) { 02553 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry, p->lastms); 02554 } 02555 }
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 = "6989f2ec67f8497e38c12890500c525b" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 19347 of file chan_sip.c.
struct in_addr __ourip [static] |
Definition at line 1233 of file chan_sip.c.
int allow_external_domains [static] |
Accept calls to external SIP domains?
Definition at line 567 of file chan_sip.c.
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 587 of file chan_sip.c.
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 18824 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 18826 of file chan_sip.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 19347 of file chan_sip.c.
Definition at line 1222 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 547 of file chan_sip.c.
struct sockaddr_in bindaddr = { 0, } [static] |
The address we bind to
Definition at line 1227 of file chan_sip.c.
struct ast_threadstorage check_auth_buf = { .once = PTHREAD_ONCE_INIT, .key_init = check_auth_buf_init , } [static] |
Definition at line 8754 of file chan_sip.c.
Referenced by check_auth(), and transmit_fake_auth_response().
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 19086 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 19091 of file chan_sip.c.
int compactheaders [static] |
send compact sip headers
Definition at line 561 of file chan_sip.c.
const char config[] = "sip.conf" [static] |
Definition at line 233 of file chan_sip.c.
char debug_usage[] [static] |
Definition at line 12225 of file chan_sip.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1236 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 527 of file chan_sip.c.
char default_context[AST_MAX_CONTEXT] [static] |
Definition at line 524 of file chan_sip.c.
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 193 of file chan_sip.c.
char default_fromdomain[AST_MAX_EXTENSION] [static] |
Definition at line 528 of file chan_sip.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled.
Definition at line 224 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Definition at line 526 of file chan_sip.c.
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 535 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 532 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 533 of file chan_sip.c.
char default_notifymime[AST_MAX_EXTENSION] [static] |
Definition at line 529 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 536 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 530 of file chan_sip.c.
char default_subscribecontext[AST_MAX_CONTEXT] [static] |
Definition at line 525 of file chan_sip.c.
char default_vmexten[AST_MAX_EXTENSION] [static] |
Definition at line 531 of file chan_sip.c.
char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static] |
Definition at line 18823 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 18829 of file chan_sip.c.
int dumphistory [static] |
Dump history to verbose before destroying SIP dialog
Definition at line 563 of file chan_sip.c.
int expiry = DEFAULT_EXPIRY [static] |
Definition at line 194 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 1230 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 1229 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 1228 of file chan_sip.c.
int externrefresh = 10 [static] |
int global_allowguest [static] |
allow unauthenticated users/peers to connect?
Definition at line 554 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 555 of file chan_sip.c.
enum transfermodes global_allowtransfer [static] |
SIP Refer restriction scheme
Definition at line 571 of file chan_sip.c.
int global_alwaysauthreject [static] |
Send 401 Unauthorized for all failing requests
Definition at line 544 of file chan_sip.c.
int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 570 of file chan_sip.c.
int global_callevents [static] |
Whether we send manager events or not
Definition at line 568 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 579 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 539 of file chan_sip.c.
int global_dynamic_exclude_static = 0 [static] |
Definition at line 580 of file chan_sip.c.
struct ast_flags global_flags[2] = {{0}} [static] |
global SIP_ flags
Definition at line 590 of file chan_sip.c.
Referenced by build_peer(), build_radius_record(), build_user(), destroy_association(), get_destination(), handle_response_peerpoke(), 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_poke_noanswer(), sip_show_settings(), transmit_response_using_temp(), and update_peer().
struct ast_jb_conf global_jbconf [static] |
Definition at line 231 of file chan_sip.c.
int global_limitonpeers [static] |
Match call limit on peers only
Definition at line 540 of file chan_sip.c.
int global_matchexterniplocally [static] |
Match externip/externhost setting against localnet setting
Definition at line 573 of file chan_sip.c.
int global_mwitime [static] |
Time between MWI checks for peers
Definition at line 557 of file chan_sip.c.
int global_notifyhold [static] |
Send notifications on hold
Definition at line 543 of file chan_sip.c.
int global_notifyringing [static] |
Send notifications on ringing
Definition at line 542 of file chan_sip.c.
char global_realm[MAXHOSTNAMELEN] [static] |
Default realm
Definition at line 564 of file chan_sip.c.
int global_reg_timeout [static] |
Definition at line 552 of file chan_sip.c.
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 553 of file chan_sip.c.
char global_regcontext[AST_MAX_CONTEXT] [static] |
Context for auto-extensions
Definition at line 565 of file chan_sip.c.
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 548 of file chan_sip.c.
int global_rtautoclear [static] |
Definition at line 541 of file chan_sip.c.
int global_rtpholdtimeout [static] |
Definition at line 550 of file chan_sip.c.
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 551 of file chan_sip.c.
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 549 of file chan_sip.c.
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 569 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 842 of file chan_sip.c.
unsigned int global_tos_audio [static] |
IP type of service for audio RTP packets
Definition at line 559 of file chan_sip.c.
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 558 of file chan_sip.c.
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 560 of file chan_sip.c.
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 566 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 12242 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 = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } [static] |
struct io_context* io [static] |
The IO context
Definition at line 611 of file chan_sip.c.
List of local networks, on the same side of NAT as this Asterisk
Definition at line 1232 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 10848 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 10399 of file chan_sip.c.
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Maximum accepted registration time
Definition at line 192 of file chan_sip.c.
int min_expiry = DEFAULT_MIN_EXPIRY [static] |
Minimum accepted registration time
Definition at line 191 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 605 of file chan_sip.c.
ast_mutex_t monlock = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INITIALIZER } [static] |
Definition at line 599 of file chan_sip.c.
ast_mutex_t netlock = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, 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 597 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 12234 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 12238 of file chan_sip.c.
const char notify_config[] = "sip_notify.conf" [static] |
Definition at line 234 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 1238 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 12174 of file chan_sip.c.
int ourport [static] |
Definition at line 1235 of file chan_sip.c.
struct sockaddr_in outboundproxyip [static] |
Definition at line 1234 of file chan_sip.c.
int pedanticsipchecking [static] |
Extra checking ? Default off
Definition at line 546 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 12216 of file chan_sip.c.
int recordhistory [static] |
Record SIP history. Off by default
Definition at line 562 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 588 of file chan_sip.c.
int rpeerobjs = 0 [static] |
Realtime peers
Definition at line 586 of file chan_sip.c.
int ruserobjs = 0 [static] |
Realtime users
Definition at line 584 of file chan_sip.c.
struct sched_context* sched [static] |
The scheduling context
Definition at line 610 of file chan_sip.c.
char seen_lastms = 0 [static] |
Definition at line 195 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 12198 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 12194 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 12169 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 12202 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 12189 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 12255 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 12211 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 12206 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 12221 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 12259 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 12251 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 12184 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 12179 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 = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, 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 12247 of file chan_sip.c.
int sip_reloading = FALSE [static] |
Flag for avoiding multiple reloads at the same time
Definition at line 607 of file chan_sip.c.
enum channelreloadreason sip_reloadreason [static] |
Reason for last reload/load of configuration
Definition at line 608 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 1635 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 1577 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 1603 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 1644 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 12500 of file chan_sip.c.
Referenced by load_module(), and unload_module().
Structure to declare a dialplan function: SIPPEER.
Definition at line 12420 of file chan_sip.c.
Referenced by load_module(), and unload_module().
int sipsock = -1 [static] |
Main socket for SIP network communication
Definition at line 1226 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 612 of file chan_sip.c.
int speerobjs = 0 [static] |
Statis peers
Definition at line 585 of file chan_sip.c.
int srvlookup [static] |
SRV Lookup on or off. Default is on
Definition at line 545 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 583 of file chan_sip.c.
char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static] |
Definition at line 18822 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 18827 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.