#include "asterisk.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <regex.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/compiler.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"
Go to the source code of this file.
Data Structures | |
struct | ast_peer_list |
The peer list: Peers and Friends. More... | |
struct | ast_register_list |
The register list: Other SIP proxys we register with and place calls to. More... | |
struct | ast_user_list |
The user list: Users and friends. More... | |
struct | c_referstatusstring |
struct | cfsip_methods |
struct | cfsip_options |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More... | |
struct | cfsubscription_types |
struct | domain |
Domain data structure. More... | |
struct | domain_list |
struct | sip_auth |
sip_auth: Credentials for authentication to other SIP services More... | |
struct | sip_dual |
structure used in transfers More... | |
struct | sip_history |
sip_history: Structure for saving transactions within a SIP dialog More... | |
struct | sip_history_head |
struct | sip_invite_param |
Parameters to the transmit_invite function. More... | |
struct | sip_peer |
Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host). More... | |
struct | sip_pkt |
sip packet - raw format for outbound packets that are sent or scheduled for transmission More... | |
struct | sip_pvt |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe More... | |
struct | sip_pvt::request_queue |
struct | sip_refer |
Structure to handle SIP transfers. Dynamically allocated when needed. More... | |
struct | sip_registry |
Registrations with other SIP proxies. More... | |
struct | sip_request |
sip_request: The data grabbed from the UDP socket More... | |
struct | sip_route |
Structure to save routing information for a SIP session. More... | |
struct | sip_user |
Structure for SIP user data. User's place calls to us. More... | |
struct | t38properties |
T.38 channel settings (at some point we need to make this alloc'ed. More... | |
Defines | |
#define | ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
SIP Methods we support. | |
#define | append_history(p, event, fmt, args...) append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history. | |
#define | CALLERID_UNKNOWN "Unknown" |
#define | CAN_CREATE_DIALOG 1 |
#define | CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
#define | CAN_NOT_CREATE_DIALOG 0 |
#define | CHECK_AUTH_BUF_INITLEN 256 |
#define | DEC_CALL_LIMIT 0 |
#define | DEC_CALL_RINGING 2 |
#define | DEFAULT_ALLOW_EXT_DOM TRUE |
#define | DEFAULT_ALLOWGUEST TRUE |
#define | DEFAULT_AUTOCREATEPEER FALSE |
#define | DEFAULT_CALLERID "asterisk" |
#define | DEFAULT_COMPACTHEADERS FALSE |
#define | DEFAULT_CONTEXT "default" |
#define | DEFAULT_DEFAULT_EXPIRY 120 |
#define | DEFAULT_EXPIRY 900 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_CALL_BITRATE (384) |
#define | DEFAULT_MAX_EXPIRY 3600 |
#define | DEFAULT_MAX_FORWARDS "70" |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_MIN_EXPIRY 60 |
#define | DEFAULT_MOHINTERPRET "default" |
#define | DEFAULT_MOHSUGGEST "" |
#define | DEFAULT_MWITIME 10 |
#define | DEFAULT_NOTIFYMIME "application/simple-message-summary" |
#define | DEFAULT_NOTIFYRINGING TRUE |
#define | DEFAULT_PEDANTIC FALSE |
#define | DEFAULT_QUALIFY FALSE |
#define | DEFAULT_REALM "asterisk" |
#define | DEFAULT_REGISTRATION_TIMEOUT 20 |
#define | DEFAULT_RETRANS 1000 |
#define | DEFAULT_SRVLOOKUP TRUE |
#define | DEFAULT_T1MIN 100 |
#define | DEFAULT_TOS_AUDIO 0 |
#define | DEFAULT_TOS_SIP 0 |
#define | DEFAULT_TOS_VIDEO 0 |
#define | DEFAULT_TRANS_TIMEOUT -1 |
#define | DEFAULT_USERAGENT "Asterisk PBX" |
#define | DEFAULT_VMEXTEN "asterisk" |
#define | EXPIRY_GUARD_LIMIT 30 |
#define | EXPIRY_GUARD_MIN 500 |
#define | EXPIRY_GUARD_PCT 0.20 |
#define | EXPIRY_GUARD_SECS 15 |
#define | FALSE 0 |
#define | FLAG_FATAL (1 << 1) |
#define | FLAG_RESPONSE (1 << 0) |
#define | FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" |
#define | FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" |
#define | FORMAT "%-40.40s %-20.20s %-16.16s\n" |
#define | FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
#define | FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" |
#define | FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" |
#define | FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define | FORMAT3H "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" |
#define | FORMAT3L "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" |
#define | INC_CALL_LIMIT 1 |
#define | INC_CALL_RINGING 3 |
#define | INITIAL_CSEQ 101 |
#define | IPTOS_MINCOST 0x02 |
#define | MAX(a, b) ((a) > (b) ? (a) : (b)) |
#define | MAX_AUTHTRIES 3 |
#define | MAX_HISTORY_ENTRIES 50 |
#define | MAX_RETRANS 6 |
#define | NO_RTP 0 |
#define | NOT_SUPPORTED 0 |
#define | RTP 1 |
#define | SDP_MAX_RTPMAP_CODECS 32 |
#define | SDP_SAMPLE_RATE(x) 8000 |
#define | SIP_ALREADYGONE (1 << 0) |
#define | SIP_CALL_LIMIT (1 << 28) |
#define | SIP_CAN_REINVITE (1 << 20) |
#define | SIP_CAN_REINVITE_NAT (2 << 20) |
#define | SIP_DEFER_BYE_ON_TRANSFER (1 << 15) |
#define | SIP_DTMF (3 << 16) |
#define | SIP_DTMF_AUTO (3 << 16) |
#define | SIP_DTMF_INBAND (1 << 16) |
#define | SIP_DTMF_INFO (2 << 16) |
#define | SIP_DTMF_RFC2833 (0 << 16) |
#define | SIP_FLAGS_TO_COPY |
#define | SIP_FREE_BIT (1 << 14) |
#define | SIP_G726_NONSTANDARD (1 << 31) |
#define | SIP_GOTREFER (1 << 7) |
#define | SIP_INC_COUNT (1 << 30) |
#define | SIP_INSECURE_INVITE (1 << 24) |
#define | SIP_INSECURE_PORT (1 << 23) |
#define | SIP_MAX_HEADERS 64 |
#define | SIP_MAX_LINES 64 |
#define | SIP_MAX_PACKET 4096 |
#define | SIP_NAT (3 << 18) |
#define | SIP_NAT_ALWAYS (3 << 18) |
#define | SIP_NAT_NEVER (0 << 18) |
#define | SIP_NAT_RFC3581 (1 << 18) |
#define | SIP_NAT_ROUTE (2 << 18) |
#define | SIP_NEEDDESTROY (1 << 1) |
#define | SIP_NEEDREINVITE (1 << 5) |
#define | SIP_NO_HISTORY (1 << 27) |
#define | SIP_NOVIDEO (1 << 2) |
#define | SIP_OPT_100REL (1 << 1) |
#define | SIP_OPT_EARLY_SESSION (1 << 3) |
#define | SIP_OPT_EVENTLIST (1 << 11) |
#define | SIP_OPT_GRUU (1 << 12) |
#define | SIP_OPT_HISTINFO (1 << 15) |
#define | SIP_OPT_JOIN (1 << 4) |
#define | SIP_OPT_NOREFERSUB (1 << 14) |
#define | SIP_OPT_PATH (1 << 5) |
#define | SIP_OPT_PRECONDITION (1 << 7) |
#define | SIP_OPT_PREF (1 << 6) |
#define | SIP_OPT_PRIVACY (1 << 8) |
#define | SIP_OPT_REPLACES (1 << 0) |
#define | SIP_OPT_RESPRIORITY (1 << 16) |
#define | SIP_OPT_SDP_ANAT (1 << 9) |
#define | SIP_OPT_SEC_AGREE (1 << 10) |
#define | SIP_OPT_TARGET_DIALOG (1 << 13) |
#define | SIP_OPT_TIMER (1 << 2) |
#define | SIP_OUTGOING (1 << 13) |
#define | SIP_PAGE2_ALLOWOVERLAP (1 << 17) |
#define | SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
#define | SIP_PAGE2_BUGGY_MWI (1 << 26) |
#define | SIP_PAGE2_CALL_ONHOLD (3 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_ACTIVE (1 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_INACTIVE (3 << 23) |
#define | SIP_PAGE2_CALL_ONHOLD_ONEDIR (2 << 23) |
#define | SIP_PAGE2_DEBUG (3 << 11) |
#define | SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
#define | SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
#define | SIP_PAGE2_DIALOG_ESTABLISHED (1 << 29) |
#define | SIP_PAGE2_DYNAMIC (1 << 13) |
#define | SIP_PAGE2_FLAGS_TO_COPY |
#define | SIP_PAGE2_IGNOREREGEXPIRE (1 << 10) |
#define | SIP_PAGE2_INC_RINGING (1 << 19) |
#define | SIP_PAGE2_OUTGOING_CALL (1 << 27) |
#define | SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) |
#define | SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
#define | SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
#define | SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
#define | SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
#define | SIP_PAGE2_RTUPDATE (1 << 1) |
#define | SIP_PAGE2_SELFDESTRUCT (1 << 14) |
#define | SIP_PAGE2_STATECHANGEQUEUE (1 << 9) |
#define | SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
#define | SIP_PAGE2_T38SUPPORT (7 << 20) |
#define | SIP_PAGE2_T38SUPPORT_RTP (2 << 20) |
#define | SIP_PAGE2_T38SUPPORT_TCP (4 << 20) |
#define | SIP_PAGE2_T38SUPPORT_UDPTL (1 << 20) |
#define | SIP_PAGE2_UDPTL_DESTINATION (1 << 28) |
#define | SIP_PAGE2_VIDEOSUPPORT (1 << 15) |
#define | SIP_PENDINGBYE (1 << 6) |
#define | SIP_PKT_DEBUG (1 << 0) |
#define | SIP_PKT_IGNORE (1 << 2) |
#define | SIP_PKT_IGNORE_REQ (1 << 4) |
#define | SIP_PKT_IGNORE_RESP (1 << 3) |
#define | SIP_PKT_WITH_TOTAG (1 << 1) |
#define | SIP_PROG_INBAND (3 << 25) |
#define | SIP_PROG_INBAND_NEVER (0 << 25) |
#define | SIP_PROG_INBAND_NO (1 << 25) |
#define | SIP_PROG_INBAND_YES (2 << 25) |
#define | SIP_PROGRESS_SENT (1 << 4) |
#define | SIP_PROMISCREDIR (1 << 8) |
#define | SIP_REALTIME (1 << 11) |
#define | SIP_REINVITE (7 << 20) |
#define | SIP_REINVITE_UPDATE (4 << 20) |
#define | SIP_RINGING (1 << 3) |
#define | SIP_SENDRPID (1 << 29) |
#define | SIP_TRANS_TIMEOUT 32000 |
#define | SIP_TRUSTRPID (1 << 9) |
#define | SIP_USECLIENTCODE (1 << 12) |
#define | SIP_USEREQPHONE (1 << 10) |
#define | SIPBUFSIZE 512 |
#define | sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG) |
#define | sipdebug_config ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG) |
#define | sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
#define | STANDARD_SIP_PORT 5060 |
Standard SIP port from RFC 3261. DO NOT CHANGE THIS. | |
#define | SUPPORTED 1 |
#define | SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support. | |
#define | T38FAX_FILL_BIT_REMOVAL (1 << 0) |
#define | T38FAX_RATE_12000 (1 << 12) |
#define | T38FAX_RATE_14400 (1 << 13) |
#define | T38FAX_RATE_2400 (1 << 8) |
#define | T38FAX_RATE_4800 (1 << 9) |
#define | T38FAX_RATE_7200 (1 << 10) |
#define | T38FAX_RATE_9600 (1 << 11) |
#define | T38FAX_RATE_MANAGEMENT_LOCAL_TCF (1 << 3) |
#define | T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
#define | T38FAX_TRANSCODING_JBIG (1 << 2) |
#define | T38FAX_TRANSCODING_MMR (1 << 1) |
#define | T38FAX_UDP_EC_FEC (1 << 4) |
#define | T38FAX_UDP_EC_NONE (0 << 4) |
#define | T38FAX_UDP_EC_REDUNDANCY (2 << 4) |
#define | T38FAX_VERSION (3 << 6) |
#define | T38FAX_VERSION_0 (0 << 6) |
#define | T38FAX_VERSION_1 (1 << 6) |
#define | TRUE 1 |
#define | UNLINK(element, head, prev) |
#define | VIDEO_CODEC_MASK 0x1fc0000 |
#define | XMIT_ERROR -2 |
Enumerations | |
enum | check_auth_result { AUTH_SUCCESSFUL = 0, AUTH_CHALLENGE_SENT = 1, AUTH_SECRET_FAILED = -1, AUTH_USERNAME_MISMATCH = -2, AUTH_NOT_FOUND = -3, AUTH_FAKE_AUTH = -4, AUTH_UNKNOWN_DOMAIN = -5, AUTH_PEER_NOT_DYNAMIC = -6, AUTH_ACL_FAILED = -7 } |
Authentication result from check_auth* functions. More... | |
enum | domain_mode { SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG } |
Modes for SIP domain handling in the PBX. More... | |
enum | invitestates { INV_NONE = 0, INV_CALLING = 1, INV_PROCEEDING = 2, INV_EARLY_MEDIA = 3, INV_COMPLETED = 4, INV_CONFIRMED = 5, INV_TERMINATED = 6, INV_CANCELLED = 7 } |
States for the INVITE transaction, not the dialog. More... | |
enum | parse_register_result { PARSE_REGISTER_FAILED, PARSE_REGISTER_UPDATE, PARSE_REGISTER_QUERY } |
enum | referstatus { REFER_IDLE, REFER_SENT, REFER_RECEIVED, REFER_CONFIRMED, REFER_ACCEPTED, REFER_RINGING, REFER_200OK, REFER_FAILED, REFER_NOAUTH } |
Parameters to know status of transfer. More... | |
enum | sip_auth_type { PROXY_AUTH, WWW_AUTH } |
Authentication types - proxy or www authentication. More... | |
enum | sip_result { AST_SUCCESS = 0, AST_FAILURE = -1 } |
enum | sipmethod { SIP_UNKNOWN, SIP_RESPONSE, SIP_REGISTER, SIP_OPTIONS, SIP_NOTIFY, SIP_INVITE, SIP_ACK, SIP_PRACK, SIP_BYE, SIP_REFER, SIP_SUBSCRIBE, SIP_MESSAGE, SIP_UPDATE, SIP_INFO, SIP_CANCEL, SIP_PUBLISH, SIP_PING } |
SIP Request methods known by Asterisk. More... | |
enum | sipregistrystate { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH, REG_STATE_FAILED } |
States for outbound registrations (with register= lines in sip.conf. More... | |
enum | subscriptiontype { NONE = 0, XPIDF_XML, DIALOG_INFO_XML, CPIM_PIDF_XML, PIDF_XML, MWI_NOTIFICATION } |
enum | t38state { T38_DISABLED = 0, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, T38_PEER_DIRECT, T38_PEER_REINVITE, T38_ENABLED } |
T38 States for a call. More... | |
enum | transfermodes { TRANSFER_OPENFORALL, TRANSFER_CLOSED } |
Authorization scheme for call transfers. More... | |
enum | xmittype { XMIT_CRITICAL = 2, XMIT_RELIABLE = 1, XMIT_UNRELIABLE = 0 } |
Functions | |
static const char * | __get_header (const struct sip_request *req, const char *name, int *start) |
static void | __reg_module (void) |
static int | __set_address_from_contact (const char *fullcontact, struct sockaddr_in *sin) |
static void | __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
Acknowledges receipt of a packet and stops retransmission called with p locked. | |
static int | __sip_autodestruct (const void *data) |
Kill a SIP dialog (called by scheduler). | |
static int | __sip_destroy (struct sip_pvt *p, int lockowner) |
Execute destruction of SIP dialog structure, release memory. | |
static int | __sip_do_register (struct sip_registry *r) |
Register with SIP proxy. | |
static void | __sip_pretend_ack (struct sip_pvt *p) |
Pretend to ack all packets called with p locked. | |
static int | __sip_reliable_xmit (struct sip_pvt *p, int seqno, int resp, char *data, int len, int fatal, int sipmethod) |
Transmit packet with retransmits. | |
static int | __sip_semi_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
Acks receipt of packet, keep it around (used for provisional responses). | |
static int | __sip_show_channels (int fd, int argc, char *argv[], int subscriptions) |
SIP show channels CLI (main function). | |
static int | __sip_xmit (struct sip_pvt *p, char *data, int len) |
Transmit SIP message. | |
static int | __transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Base transmit response function. | |
static void | __unreg_module (void) |
static int | _sip_show_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
Show one peer in detail (main function). | |
static int | _sip_show_peers (int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
_sip_show_peers: Execute sip show peers command | |
static int | acf_channel_read (struct ast_channel *chan, char *funcname, char *preparse, char *buf, size_t buflen) |
static void | add_blank (struct sip_request *req) |
add a blank line if no body | |
static void | add_codec_to_sdp (const struct sip_pvt *p, int codec, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug, int *min_packet_size) |
Add codec offer to SDP offer/answer body in INVITE or 200 OK. | |
static int | add_digit (struct sip_request *req, char digit, unsigned int duration) |
Add DTMF INFO tone to sip message. | |
static int | add_header (struct sip_request *req, const char *var, const char *value) |
Add header to SIP message. | |
static int | add_header_contentLength (struct sip_request *req, int len) |
Add 'Content-Length' header to SIP message. | |
static int | add_line (struct sip_request *req, const char *line) |
Add content (not header) to SIP message. | |
static void | add_noncodec_to_sdp (const struct sip_pvt *p, int format, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug) |
Add RFC 2833 DTMF offer to SDP. | |
static struct sip_auth * | add_realm_authentication (struct sip_auth *authlist, char *configuration, int lineno) |
Add realm authentication in list. | |
static void | add_route (struct sip_request *req, struct sip_route *route) |
Add route header into request per learned route. | |
static enum sip_result | add_sdp (struct sip_request *resp, struct sip_pvt *p) |
Add Session Description Protocol message. | |
static int | add_sip_domain (const char *domain, const enum domain_mode mode, const char *context) |
Add SIP domain to list of domains we are responsible for. | |
static int | add_t38_sdp (struct sip_request *resp, struct sip_pvt *p) |
Add T.38 Session Description Protocol message. | |
static int | add_text (struct sip_request *req, const char *text) |
Add text body to SIP message. | |
static int | add_vidupdate (struct sip_request *req) |
add XML encoded media control with update | |
static void | append_date (struct sip_request *req) |
Append date to SIP message. | |
static void | append_history_full (struct sip_pvt *p, const char *fmt,...) |
Append to SIP dialog history with arg list. | |
static void | append_history_va (struct sip_pvt *p, const char *fmt, va_list ap) |
Append to SIP dialog history with arg list. | |
static void | ast_quiet_chan (struct ast_channel *chan) |
Turn off generator data XXX Does this function belong in the SIP channel? | |
static int | ast_sip_ouraddrfor (struct in_addr *them, struct in_addr *us) |
NAT fix - decide which IP address to use for ASterisk server? | |
static int | attempt_transfer (struct sip_dual *transferer, struct sip_dual *target) |
Attempt transfer of SIP call This fix for attended transfers on a local PBX. | |
static int | auto_congest (const void *nothing) |
Scheduled congestion on a call. | |
static void | build_callid_pvt (struct sip_pvt *pvt) |
Build SIP Call-ID value for a non-REGISTER transaction. | |
static void | build_callid_registry (struct sip_registry *reg, struct in_addr ourip, const char *fromdomain) |
Build SIP Call-ID value for a REGISTER transaction. | |
static void | build_contact (struct sip_pvt *p) |
Build contact header - the contact header we send out. | |
static struct sip_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
Build peer from configuration (file or realtime static/dynamic). | |
static int | build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len) |
Build reply digest. | |
static void | build_route (struct sip_pvt *p, struct sip_request *req, int backwards) |
Build route list from Record-Route header. | |
static void | build_rpid (struct sip_pvt *p) |
Build the Remote Party-ID & From using callingpres options. | |
static struct sip_user * | build_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
Initiate a SIP user structure from configuration (configuration or realtime). | |
static void | build_via (struct sip_pvt *p) |
Build a Via header for a request. | |
static int | cb_extensionstate (char *context, char *exten, int state, void *data) |
Callback for the devicestate notification (SUBSCRIBE) support subsystem. | |
static void | change_hold_state (struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly) |
Change hold state for a call. | |
static enum check_auth_result | check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, char *uri, enum xmittype reliable, int ignore) |
Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set). | |
static void | check_auth_buf_init (void) |
static void | check_pendings (struct sip_pvt *p) |
Check pending actions on SIP call. | |
static int | check_sip_domain (const char *domain, char *context, size_t len) |
check_sip_domain: Check if domain part of uri is local to our server | |
static int | check_user (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin) |
Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced. | |
static enum check_auth_result | check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin, struct sip_peer **authpeer) |
Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests. | |
static void | check_via (struct sip_pvt *p, const struct sip_request *req) |
check Via: header for hostname, port and rport request/answer | |
static void | cleanup_stale_contexts (char *new, char *old) |
Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly. | |
static int | clear_realm_authentication (struct sip_auth *authlist) |
Clear realm authentication list (at reload). | |
static void | clear_sip_domains (void) |
Clear our domain list (at reload). | |
static char * | complete_sip_debug_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip debug peer' CLI. | |
static char * | complete_sip_peer (const char *word, int state, int flags2) |
Do completion on peer name. | |
static char * | complete_sip_prune_realtime_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip prune realtime peer' CLI. | |
static char * | complete_sip_prune_realtime_user (const char *line, const char *word, int pos, int state) |
Support routine for 'sip prune realtime user' CLI. | |
static char * | complete_sip_show_peer (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show peer' CLI. | |
static char * | complete_sip_show_user (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show user' CLI. | |
static char * | complete_sip_user (const char *word, int state, int flags2) |
Do completion on user name. | |
static char * | complete_sipch (const char *line, const char *word, int pos, int state) |
Support routine for 'sip show channel' CLI. | |
static char * | complete_sipnotify (const char *line, const char *word, int pos, int state) |
Support routine for 'sip notify' CLI. | |
static int | copy_all_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy all headers from one request to another. | |
static int | copy_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy one header field from one request to another. | |
static void | copy_request (struct sip_request *dst, const struct sip_request *src) |
copy SIP request (mostly used to save request for responses) | |
static int | copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field) |
Copy SIP VIA Headers from the request to the response. | |
static int | create_addr (struct sip_pvt *dialog, const char *opeer, 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_msg_text (char *buf, int len, struct sip_request *req) |
Get text out of a SIP MESSAGE packet. | |
static int | get_rdnis (struct sip_pvt *p, struct sip_request *oreq) |
Get referring dnis. | |
static int | get_refer_info (struct sip_pvt *transferer, struct sip_request *outgoing_req) |
Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure. | |
static int | get_rpid_num (const char *input, char *output, int maxlen) |
Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found. | |
static const char * | get_sdp (struct sip_request *req, const char *name) |
Get a line from an SDP message body. | |
static const char * | get_sdp_iterate (int *start, struct sip_request *req, const char *name) |
Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number. | |
static struct sip_pvt * | get_sip_pvt_byid_locked (const char *callid, const char *totag, const char *fromtag) |
Lock interface lock and find matching pvt lock. | |
static const char * | gettag (const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize) |
Get tag from packet. | |
static int | handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v) |
Handle flag-type options common to configuration of devices - users and peers. | |
static int | handle_invite_replaces (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin) |
Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. | |
static int | handle_request (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock) |
Handle incoming SIP requests (methods). | |
static int | handle_request_bye (struct sip_pvt *p, struct sip_request *req) |
Handle incoming BYE request. | |
static int | handle_request_cancel (struct sip_pvt *p, struct sip_request *req) |
Handle incoming CANCEL request. | |
static void | handle_request_info (struct sip_pvt *p, struct sip_request *req) |
Receive SIP INFO Message. | |
static int | handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, char *e, int *nounlock) |
Handle incoming INVITE request. | |
static int | handle_request_message (struct sip_pvt *p, struct sip_request *req) |
Handle incoming MESSAGE request. | |
static int | handle_request_notify (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e) |
Handle incoming notifications. | |
static int | handle_request_options (struct sip_pvt *p, struct sip_request *req) |
Handle incoming OPTIONS request. | |
static int | handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, int *nounlock) |
static int | handle_request_register (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, char *e) |
Handle incoming REGISTER request. | |
static int | handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e) |
Handle incoming SUBSCRIBE request. | |
static void | handle_response (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
Handle SIP response in dialogue. | |
static void | handle_response_invite (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno) |
Handle SIP response to INVITE dialogue. | |
static void | handle_response_peerpoke (struct sip_pvt *p, int resp, struct sip_request *req) |
Handle qualification responses (OPTIONS). | |
static void | handle_response_refer (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno) |
static int | handle_response_register (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
Handle responses on REGISTER to services. | |
static const char * | hangup_cause2sip (int cause) |
Convert Asterisk hangup causes to SIP codes. | |
static int | hangup_sip2cause (int cause) |
Convert SIP hangup causes to Asterisk hangup causes. | |
static int | init_req (struct sip_request *req, int sipmethod, const char *recip) |
Initialize SIP request. | |
static int | init_resp (struct sip_request *resp, const char *msg) |
Initialize SIP response, based on SIP request. | |
static void | initialize_initreq (struct sip_pvt *p, struct sip_request *req) |
Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog. | |
static void | initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod) |
Initiate new SIP request to peer/user. | |
static const char * | insecure2str (int port, int invite) |
Convert Insecure setting to printable string. | |
static void | list_route (struct sip_route *route) |
List all routes - mostly for debugging. | |
static int | load_module (void) |
PBX load module - initialization. | |
static int | local_attended_transfer (struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno) |
Find all call legs and bridge transferee with target called from handle_request_refer. | |
static int | lws2sws (char *msgbuf, int len) |
Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled. | |
static void | make_our_tag (char *tagbuf, size_t len) |
Make our SIP dialog tag. | |
static int | manager_sip_show_peer (struct mansession *s, const struct message *m) |
Show SIP peers in the manager API. | |
static int | manager_sip_show_peers (struct mansession *s, const struct message *m) |
Show SIP peers in the manager API. | |
static int | method_match (enum sipmethod id, const char *name) |
returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send | |
static char * | nat2str (int nat) |
Convert NAT setting to text string. | |
static void | parse_copy (struct sip_request *dst, const struct sip_request *src) |
Copy SIP request, parse it. | |
static void | parse_moved_contact (struct sip_pvt *p, struct sip_request *req) |
Parse 302 Moved temporalily response. | |
static int | parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req) |
Save contact header for 200 OK on INVITE. | |
static enum parse_register_result | parse_register_contact (struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req) |
Parse contact header and save registration (peer registration). | |
static int | parse_request (struct sip_request *req) |
Parse a SIP message. | |
static unsigned int | parse_sip_options (struct sip_pvt *pvt, const char *supported) |
Parse supported header in incoming packet. | |
static int | peer_status (struct sip_peer *peer, char *status, int statuslen) |
Report Peer status in character string. | |
static void | print_codec_to_cli (int fd, struct ast_codec_pref *pref) |
Print codec list from preference to CLI/manager. | |
static void | print_group (int fd, ast_group_t group, int crlf) |
Print call group and pickup group. | |
static void | process_request_queue (struct sip_pvt *p, int *recount, int *nounlock) |
static int | process_sdp (struct sip_pvt *p, struct sip_request *req) |
Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp(). | |
static int | queue_request (struct sip_pvt *p, const struct sip_request *req) |
static struct sip_peer * | realtime_peer (const char *newpeername, struct sockaddr_in *sin, int devstate_only) |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf | |
static void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey, 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_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 = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, .reload = reload, } |
static struct in_addr | __ourip |
static int | allow_external_domains |
static int | apeerobjs = 0 |
static char * | app_dtmfmode = "SIPDtmfMode" |
static char * | app_sipaddheader = "SIPAddHeader" |
static const struct ast_module_info * | ast_module_info = &__mod_info |
static struct sip_auth * | authl = NULL |
static int | autocreatepeer |
static struct sockaddr_in | bindaddr = { 0, } |
static struct ast_threadstorage | check_auth_buf = { .once = PTHREAD_ONCE_INIT, .key_init = check_auth_buf_init , } |
static struct ast_custom_function | checksipdomain_function |
static struct ast_cli_entry | cli_sip [] |
static struct ast_cli_entry | cli_sip_debug_deprecated |
static struct ast_cli_entry | cli_sip_no_debug_deprecated |
static int | compactheaders |
static const char | config [] = "sip.conf" |
static char | debug_usage [] |
static struct sockaddr_in | debugaddr |
static char | default_callerid [AST_MAX_EXTENSION] |
static char | default_context [AST_MAX_CONTEXT] |
static int | default_expiry = DEFAULT_DEFAULT_EXPIRY |
static char | default_fromdomain [AST_MAX_EXTENSION] |
static struct ast_jb_conf | default_jbconf |
Global jitterbuffer configuration - by default, jb is disabled. | |
static char | default_language [MAX_LANGUAGE] |
static int | default_maxcallbitrate |
static char | default_mohinterpret [MAX_MUSICCLASS] |
static char | default_mohsuggest [MAX_MUSICCLASS] |
static char | default_notifymime [AST_MAX_EXTENSION] |
static struct ast_codec_pref | default_prefs |
static int | default_qualify |
static char | default_subscribecontext [AST_MAX_CONTEXT] |
static char | default_vmexten [AST_MAX_EXTENSION] |
static char * | descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" |
static char * | descrip_sipaddheader |
static int | dumphistory |
static int | expiry = DEFAULT_EXPIRY |
static time_t | externexpire = 0 |
static char | externhost [MAXHOSTNAMELEN] |
static struct sockaddr_in | externip |
static int | externrefresh = 10 |
static int | global_allowguest |
static int | global_allowsubscribe |
static enum transfermodes | global_allowtransfer |
static int | global_alwaysauthreject |
static int | global_autoframing |
static int | global_callevents |
static int | global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 |
Codecs that we support by default:. | |
static struct ast_ha * | global_contact_ha = NULL |
Global list of addresses dynamic peers are not allowed to use. | |
static int | global_directrtpsetup |
static int | global_dynamic_exclude_static = 0 |
static struct ast_flags | global_flags [2] = {{0}} |
static struct ast_jb_conf | global_jbconf |
static int | global_limitonpeers |
static int | global_matchexterniplocally |
static int | global_mwitime |
static int | global_notifyhold |
static int | global_notifyringing |
static char | global_realm [MAXHOSTNAMELEN] |
static int | global_reg_timeout |
static int | global_regattempts_max |
static char | global_regcontext [AST_MAX_CONTEXT] |
static int | global_relaxdtmf |
static int | global_rtautoclear |
static int | global_rtpholdtimeout |
static int | global_rtpkeepalive |
static int | global_rtptimeout |
static int | global_t1min |
static int | global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 |
static unsigned int | global_tos_audio |
static unsigned int | global_tos_sip |
static unsigned int | global_tos_video |
static char | global_useragent [AST_MAX_EXTENSION] |
static char | history_usage [] |
static struct sip_pvt * | iflist |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe | |
static ast_mutex_t | iflock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
Protect the SIP dialog list (of sip_pvt's). | |
static struct io_context * | io |
static struct ast_ha * | localaddr |
static char | mandescr_show_peer [] |
static char | mandescr_show_peers [] |
static int | max_expiry = DEFAULT_MAX_EXPIRY |
static int | min_expiry = DEFAULT_MIN_EXPIRY |
static pthread_t | monitor_thread = AST_PTHREADT_NULL |
This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
static ast_mutex_t | monlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static ast_mutex_t | netlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
static char | no_debug_usage [] |
static char | no_history_usage [] |
static const char | notify_config [] = "sip_notify.conf" |
static struct ast_config * | notify_types |
static char | notify_usage [] |
static int | ourport |
static struct sockaddr_in | outboundproxyip |
static int | pedanticsipchecking |
static struct ast_peer_list | peerl |
The peer list: Peers and Friends. | |
static char | prune_realtime_usage [] |
static int | recordhistory |
static struct c_referstatusstring | referstatusstrings [] |
static struct ast_register_list | regl |
The register list: Other SIP proxys we register with and place calls to. | |
static int | regobjs = 0 |
static int | rpeerobjs = 0 |
static int | ruserobjs = 0 |
static struct sched_context * | sched |
static char | show_channel_usage [] |
static char | show_channels_usage [] |
static char | show_domains_usage [] |
static char | show_history_usage [] |
static char | show_inuse_usage [] |
static char | show_objects_usage [] |
static char | show_peer_usage [] |
static char | show_peers_usage [] |
static char | show_reg_usage [] |
static char | show_settings_usage [] |
static char | show_subscriptions_usage [] |
static char | show_user_usage [] |
static char | show_users_usage [] |
static struct ast_custom_function | sip_header_function |
static struct cfsip_methods | sip_methods [] |
static struct cfsip_options | sip_options [] |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. | |
static ast_mutex_t | sip_reload_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static char | sip_reload_usage [] |
static int | sip_reloading = FALSE |
static enum channelreloadreason | sip_reloadreason |
static struct ast_rtp_protocol | sip_rtp |
Interface structure with callbacks used to connect to RTP module. | |
static struct ast_channel_tech | sip_tech |
Definition of this channel for PBX channel registration. | |
static struct ast_channel_tech | sip_tech_info |
This version of the sip channel tech has no send_digit_begin callback. This is for use with channels using SIP INFO DTMF so that the core knows that the channel doesn't want DTMF BEGIN frames. | |
static struct ast_udptl_protocol | sip_udptl |
Interface structure with callbacks used to connect to UDPTL module. | |
static struct ast_custom_function | sipchaninfo_function |
Structure to declare a dialplan function: SIPCHANINFO. | |
ast_custom_function | sippeer_function |
Structure to declare a dialplan function: SIPPEER. | |
static int | sipsock = -1 |
static int * | sipsock_read_id |
static int | 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" |
SIP Methods we support.
Definition at line 476 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 1869 of file chan_sip.c.
Referenced by __sip_autodestruct(), __sip_reliable_xmit(), auto_congest(), build_reply_digest(), cb_extensionstate(), change_hold_state(), check_auth(), do_register_auth(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), local_attended_transfer(), retrans_pkt(), send_request(), send_response(), sip_cancel_destroy(), sip_fixup(), sip_hangup(), sip_new(), sip_park_thread(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), sipsock_read(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_with_auth().
#define CALLERID_UNKNOWN "Unknown" |
#define CAN_CREATE_DIALOG 1 |
Definition at line 369 of file chan_sip.c.
#define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
Definition at line 370 of file chan_sip.c.
#define CAN_NOT_CREATE_DIALOG 0 |
Definition at line 368 of file chan_sip.c.
#define CHECK_AUTH_BUF_INITLEN 256 |
Definition at line 8673 of file chan_sip.c.
Referenced by check_auth(), and transmit_fake_auth_response().
#define DEC_CALL_LIMIT 0 |
Definition at line 613 of file chan_sip.c.
Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_hangup(), and update_call_counter().
#define DEC_CALL_RINGING 2 |
Definition at line 615 of file chan_sip.c.
Referenced by handle_response_invite(), and update_call_counter().
#define DEFAULT_ALLOW_EXT_DOM TRUE |
Definition at line 508 of file chan_sip.c.
#define DEFAULT_ALLOWGUEST TRUE |
Definition at line 502 of file chan_sip.c.
#define DEFAULT_AUTOCREATEPEER FALSE |
Definition at line 512 of file chan_sip.c.
#define DEFAULT_CALLERID "asterisk" |
Definition at line 499 of file chan_sip.c.
#define DEFAULT_COMPACTHEADERS FALSE |
Definition at line 504 of file chan_sip.c.
#define DEFAULT_CONTEXT "default" |
Definition at line 495 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 204 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 203 of file chan_sip.c.
#define DEFAULT_MAX_CALL_BITRATE (384) |
Max bitrate for video
Definition at line 515 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 202 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 496 of file chan_sip.c.
#define DEFAULT_MOHSUGGEST "" |
Definition at line 497 of file chan_sip.c.
#define DEFAULT_MWITIME 10 |
Definition at line 501 of file chan_sip.c.
#define DEFAULT_NOTIFYMIME "application/simple-message-summary" |
Definition at line 500 of file chan_sip.c.
#define DEFAULT_NOTIFYRINGING TRUE |
Definition at line 510 of file chan_sip.c.
#define DEFAULT_PEDANTIC FALSE |
Definition at line 511 of file chan_sip.c.
#define DEFAULT_QUALIFY FALSE |
Definition at line 513 of file chan_sip.c.
#define DEFAULT_REALM "asterisk" |
Definition at line 509 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 206 of file chan_sip.c.
#define DEFAULT_SRVLOOKUP TRUE |
Recommended setting is ON
Definition at line 503 of file chan_sip.c.
#define DEFAULT_T1MIN 100 |
100 MS for minimal roundtrip time
Definition at line 514 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 506 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 505 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 507 of file chan_sip.c.
#define DEFAULT_TRANS_TIMEOUT -1 |
Definition at line 211 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 517 of file chan_sip.c.
#define DEFAULT_VMEXTEN "asterisk" |
Definition at line 498 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 1037 of file chan_sip.c.
Referenced by __sip_ack(), __sip_pretend_ack(), __sip_reliable_xmit(), __sip_semi_ack(), handle_request(), and retrans_pkt().
#define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" |
#define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" |
#define FORMAT "%-40.40s %-20.20s %-16.16s\n" |
#define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" |
#define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
#define FORMAT "%-25.25s %-15.15s %-15.15s \n" |
#define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" |
#define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
#define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" |
#define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
#define FORMAT3H "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" |
Referenced by __sip_show_channels().
#define FORMAT3L "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" |
#define INC_CALL_LIMIT 1 |
Definition at line 614 of file chan_sip.c.
Referenced by handle_request_invite(), sip_hangup(), and update_call_counter().
#define INC_CALL_RINGING 3 |
#define INITIAL_CSEQ 101 |
our initial sip sequence number
Definition at line 220 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 197 of file chan_sip.c.
#define MAX_AUTHTRIES 3 |
Try authentication three times, then fail
Definition at line 212 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 1035 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 207 of file chan_sip.c.
#define NO_RTP 0 |
Definition at line 236 of file chan_sip.c.
#define NOT_SUPPORTED 0 |
Definition at line 409 of file chan_sip.c.
#define RTP 1 |
Definition at line 235 of file chan_sip.c.
#define SDP_MAX_RTPMAP_CODECS 32 |
Maximum number of codecs allowed in received SDP
Definition at line 218 of file chan_sip.c.
Referenced by process_sdp().
#define SDP_SAMPLE_RATE | ( | x | ) | 8000 |
Definition at line 6675 of file chan_sip.c.
Referenced by add_sdp().
#define SIP_ALREADYGONE (1 << 0) |
Whether or not we've already been destroyed by our peer
Definition at line 721 of file chan_sip.c.
Referenced by __sip_autodestruct(), handle_request(), handle_response_invite(), sip_alreadygone(), sip_hangup(), and sip_set_rtp_peer().
#define SIP_CALL_LIMIT (1 << 28) |
Call limit enforced for this call
Definition at line 762 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), and update_call_counter().
#define SIP_CAN_REINVITE (1 << 20) |
allow peers to be reinvited to send media directly p2p
Definition at line 750 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), sip_get_rtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), and sip_handle_t38_reinvite().
#define SIP_CAN_REINVITE_NAT (2 << 20) |
allow media reinvite when new peer is behind NAT
Definition at line 751 of file chan_sip.c.
Referenced by handle_common_options(), sip_get_rtp_peer(), and sip_set_rtp_peer().
#define SIP_DEFER_BYE_ON_TRANSFER (1 << 15) |
Do not hangup at first ast_hangup
Definition at line 736 of file chan_sip.c.
Referenced by handle_invite_replaces(), handle_request_refer(), local_attended_transfer(), sip_hangup(), and sip_set_rtp_peer().
#define SIP_DTMF (3 << 16) |
DTMF Support: four settings, uses two bits
Definition at line 737 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), create_addr_from_peer(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit_begin(), sip_senddigit_end(), sip_show_channel(), and sip_show_settings().
#define SIP_DTMF_AUTO (3 << 16) |
DTMF Support: AUTO switch between rfc2833 and in-band DTMF
Definition at line 741 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), process_sdp(), and sip_alloc().
#define SIP_DTMF_INBAND (1 << 16) |
DTMF Support: Inband audio, only for ULAW/ALAW - "inband"
Definition at line 739 of file chan_sip.c.
Referenced by dtmfmode2str(), handle_common_options(), process_sdp(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().
#define SIP_DTMF_INFO (2 << 16) |
DTMF Support: SIP Info messages - "info"
Definition at line 740 of file chan_sip.c.
Referenced by dtmfmode2str(), handle_common_options(), sip_dtmfmode(), sip_new(), and sip_senddigit_end().
#define SIP_DTMF_RFC2833 (0 << 16) |
DTMF Support: RTP DTMF - "rfc2833"
Definition at line 738 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().
#define SIP_FLAGS_TO_COPY |
Value:
(SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | \ SIP_PROG_INBAND | SIP_USECLIENTCODE | SIP_NAT | SIP_G726_NONSTANDARD | \ SIP_USEREQPHONE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE)
Definition at line 767 of file chan_sip.c.
Referenced by build_user(), check_user_full(), create_addr_from_peer(), set_peer_defaults(), sip_alloc(), and sip_poke_peer().
#define SIP_FREE_BIT (1 << 14) |
----
Definition at line 735 of file chan_sip.c.
#define SIP_G726_NONSTANDARD (1 << 31) |
Use non-standard packing for G726-32 data
Definition at line 765 of file chan_sip.c.
Referenced by add_codec_to_sdp(), handle_common_options(), and process_sdp().
#define SIP_GOTREFER (1 << 7) |
Got a refer?
Definition at line 728 of file chan_sip.c.
Referenced by handle_request_refer(), local_attended_transfer(), sip_handle_t38_reinvite(), sip_read(), sip_set_rtp_peer(), and sip_set_udptl_peer().
#define SIP_INC_COUNT (1 << 30) |
Did this connection increment the counter of in-use calls?
Definition at line 764 of file chan_sip.c.
Referenced by __sip_destroy(), handle_request_cancel(), sip_hangup(), and update_call_counter().
#define SIP_INSECURE_INVITE (1 << 24) |
don't require authentication for incoming INVITEs
Definition at line 755 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), handle_common_options(), and set_insecure_flags().
#define SIP_INSECURE_PORT (1 << 23) |
don't require matching port for incoming requests
Definition at line 754 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), set_insecure_flags(), and sip_addrcmp().
#define SIP_MAX_HEADERS 64 |
Max amount of SIP headers to read
Definition at line 214 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 215 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 216 of file chan_sip.c.
#define SIP_NAT (3 << 18) |
four settings, uses two bits
Definition at line 743 of file chan_sip.c.
Referenced by _sip_show_peer(), build_via(), copy_via_headers(), create_addr_from_peer(), handle_common_options(), process_sdp(), register_verify(), sip_alloc(), sip_nat_mode(), sip_real_dst(), sip_show_channel(), sip_show_settings(), sip_show_users(), and transmit_response_using_temp().
#define SIP_NAT_ALWAYS (3 << 18) |
NAT Both ROUTE and RFC3581
Definition at line 747 of file chan_sip.c.
Referenced by copy_via_headers(), handle_common_options(), and nat2str().
#define SIP_NAT_NEVER (0 << 18) |
No nat support
Definition at line 744 of file chan_sip.c.
Referenced by handle_common_options(), and nat2str().
#define SIP_NAT_RFC3581 (1 << 18) |
NAT RFC3581
Definition at line 745 of file chan_sip.c.
Referenced by build_via(), copy_via_headers(), handle_common_options(), and nat2str().
#define SIP_NAT_ROUTE (2 << 18) |
NAT Only ROUTE
Definition at line 746 of file chan_sip.c.
Referenced by _sip_show_peers(), check_user_full(), check_via(), create_addr_from_peer(), handle_common_options(), nat2str(), parse_register_contact(), send_request(), set_address_from_contact(), sip_alloc(), sip_nat_mode(), sip_real_dst(), and transmit_response_using_temp().
#define SIP_NEEDDESTROY (1 << 1) |
if we need to be destroyed by the monitor thread
Definition at line 722 of file chan_sip.c.
Referenced by __sip_autodestruct(), __sip_show_channels(), do_monitor(), handle_request(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), retrans_pkt(), sip_hangup(), sip_reg_timeout(), and sip_show_channel().
#define SIP_NEEDREINVITE (1 << 5) |
Do we need to send another reinvite?
Definition at line 726 of file chan_sip.c.
Referenced by check_pendings(), sip_handle_t38_reinvite(), sip_hangup(), sip_read(), sip_reinvite_retry(), sip_set_rtp_peer(), and sip_set_udptl_peer().
#define SIP_NO_HISTORY (1 << 27) |
Suppress recording request/response history
Definition at line 761 of file chan_sip.c.
Referenced by append_history_full(), do_register_auth(), handle_request_bye(), handle_request_invite(), send_request(), send_response(), sip_alloc(), sip_hangup(), sip_new(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), sipsock_read(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_using_temp().
#define SIP_NOVIDEO (1 << 2) |
Didn't get video in invite, don't offer
Definition at line 723 of file chan_sip.c.
Referenced by add_sdp(), process_sdp(), and sip_indicate().
#define SIP_OPT_100REL (1 << 1) |
Definition at line 412 of file chan_sip.c.
#define SIP_OPT_EARLY_SESSION (1 << 3) |
Definition at line 414 of file chan_sip.c.
#define SIP_OPT_EVENTLIST (1 << 11) |
Definition at line 422 of file chan_sip.c.
#define SIP_OPT_GRUU (1 << 12) |
Definition at line 423 of file chan_sip.c.
#define SIP_OPT_HISTINFO (1 << 15) |
Definition at line 426 of file chan_sip.c.
#define SIP_OPT_JOIN (1 << 4) |
Definition at line 415 of file chan_sip.c.
#define SIP_OPT_NOREFERSUB (1 << 14) |
Definition at line 425 of file chan_sip.c.
#define SIP_OPT_PATH (1 << 5) |
Definition at line 416 of file chan_sip.c.
#define SIP_OPT_PRECONDITION (1 << 7) |
Definition at line 418 of file chan_sip.c.
#define SIP_OPT_PREF (1 << 6) |
Definition at line 417 of file chan_sip.c.
#define SIP_OPT_PRIVACY (1 << 8) |
Definition at line 419 of file chan_sip.c.
#define SIP_OPT_REPLACES (1 << 0) |
#define SIP_OPT_RESPRIORITY (1 << 16) |
Definition at line 427 of file chan_sip.c.
#define SIP_OPT_SDP_ANAT (1 << 9) |
Definition at line 420 of file chan_sip.c.
#define SIP_OPT_SEC_AGREE (1 << 10) |
Definition at line 421 of file chan_sip.c.
#define SIP_OPT_TARGET_DIALOG (1 << 13) |
Definition at line 424 of file chan_sip.c.
#define SIP_OPT_TIMER (1 << 2) |
Definition at line 413 of file chan_sip.c.
#define SIP_OUTGOING (1 << 13) |
Direction of the last transaction in this dialog
Definition at line 734 of file chan_sip.c.
Referenced by handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), reqprep(), respprep(), sip_call(), sip_hangup(), sip_indicate(), sip_poke_peer(), sip_send_mwi_to_peer(), sip_show_channel(), sip_write(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_reinvite_with_t38_sdp(), and transmit_response_with_sdp().
#define SIP_PAGE2_ALLOWOVERLAP (1 << 17) |
Allow overlap dialing ?
Definition at line 789 of file chan_sip.c.
Referenced by _sip_show_peer(), get_destination(), handle_common_options(), handle_request_invite(), and sip_show_settings().
#define SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
Allow subscriptions from this peer?
Definition at line 788 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), build_user(), handle_common_options(), handle_request_subscribe(), and sip_show_settings().
#define SIP_PAGE2_BUGGY_MWI (1 << 26) |
26: Buggy CISCO MWI fix
Definition at line 801 of file chan_sip.c.
Referenced by handle_common_options(), and transmit_notify_with_mwi().
#define SIP_PAGE2_CALL_ONHOLD (3 << 23) |
Call states
Definition at line 796 of file chan_sip.c.
Referenced by __sip_destroy(), __sip_show_channels(), add_sdp(), change_hold_state(), 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 799 of file chan_sip.c.
Referenced by add_sdp(), and change_hold_state().
#define SIP_PAGE2_CALL_ONHOLD_ONEDIR (2 << 23) |
23: One directional hold
Definition at line 798 of file chan_sip.c.
Referenced by add_sdp(), and change_hold_state().
#define SIP_PAGE2_DEBUG (3 << 11) |
Definition at line 782 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
Definition at line 783 of file chan_sip.c.
#define SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
Definition at line 784 of file chan_sip.c.
Referenced by sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), and sip_no_debug_deprecated().
#define SIP_PAGE2_DIALOG_ESTABLISHED (1 << 29) |
29: Has a dialog been established?
Definition at line 804 of file chan_sip.c.
Referenced by find_call(), handle_request_bye(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), and sip_answer().
#define SIP_PAGE2_DYNAMIC (1 << 13) |
Dynamic Peers register with Asterisk
Definition at line 785 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), function_sippeer(), register_verify(), and temp_peer().
#define SIP_PAGE2_FLAGS_TO_COPY |
Value:
(SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_VIDEOSUPPORT | \ SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | SIP_PAGE2_BUGGY_MWI | SIP_PAGE2_UDPTL_DESTINATION)
Definition at line 806 of file chan_sip.c.
Referenced by build_user(), check_user_full(), create_addr_from_peer(), set_peer_defaults(), sip_alloc(), and sip_poke_peer().
#define SIP_PAGE2_IGNOREREGEXPIRE (1 << 10) |
Definition at line 781 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), and sip_show_settings().
#define SIP_PAGE2_INC_RINGING (1 << 19) |
Did this connection increment the counter of in-use calls?
Definition at line 791 of file chan_sip.c.
Referenced by update_call_counter().
#define SIP_PAGE2_OUTGOING_CALL (1 << 27) |
27: Is this an outgoing call?
Definition at line 802 of file chan_sip.c.
Referenced by get_sip_pvt_byid_locked(), sip_request_call(), and update_call_counter().
#define SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) |
25: ????
Definition at line 800 of file chan_sip.c.
Referenced by create_addr_from_peer(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), and sip_show_settings().
#define SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
Definition at line 777 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), parse_register_contact(), and reg_source_db().
#define SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
#define SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
Definition at line 774 of file chan_sip.c.
Referenced by build_peer(), complete_sip_prune_realtime_peer(), complete_sip_prune_realtime_user(), parse_register_contact(), sip_prune_realtime(), sip_show_settings(), update_call_counter(), and update_peer().
#define SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
Definition at line 778 of file chan_sip.c.
Referenced by realtime_update_peer(), and sip_show_settings().
#define SIP_PAGE2_RTUPDATE (1 << 1) |
#define SIP_PAGE2_SELFDESTRUCT (1 << 14) |
Automatic peers need to destruct themselves
Definition at line 786 of file chan_sip.c.
Referenced by expire_register(), sip_destroy_peer(), and temp_peer().
#define SIP_PAGE2_STATECHANGEQUEUE (1 << 9) |
D: Unsent state pending change exists
Definition at line 780 of file chan_sip.c.
Referenced by cb_extensionstate(), and handle_response().
#define SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
Only issue MWI notification if subscribed to
Definition at line 790 of file chan_sip.c.
Referenced by build_peer(), does_peer_need_mwi(), and register_verify().
#define SIP_PAGE2_T38SUPPORT (7 << 20) |
T38 Fax Passthrough Support
Definition at line 792 of file chan_sip.c.
Referenced by create_addr_from_peer(), and sip_alloc().
#define SIP_PAGE2_T38SUPPORT_RTP (2 << 20) |
21: T38 Fax Passthrough Support (not implemented)
Definition at line 794 of file chan_sip.c.
Referenced by _sip_show_peer(), add_sdp(), handle_common_options(), and sip_show_settings().
#define SIP_PAGE2_T38SUPPORT_TCP (4 << 20) |
22: T38 Fax Passthrough Support (not implemented)
Definition at line 795 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), and sip_show_settings().
#define SIP_PAGE2_T38SUPPORT_UDPTL (1 << 20) |
20: T38 Fax Passthrough Support
Definition at line 793 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), sip_read(), sip_rtp_read(), and sip_show_settings().
#define SIP_PAGE2_UDPTL_DESTINATION (1 << 28) |
28: Use source IP of RTP as destination if NAT is enabled
Definition at line 803 of file chan_sip.c.
Referenced by handle_common_options(), and process_sdp().
#define SIP_PAGE2_VIDEOSUPPORT (1 << 15) |
Definition at line 787 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), check_user_full(), create_addr_from_peer(), handle_common_options(), sip_alloc(), and sip_show_settings().
#define SIP_PENDINGBYE (1 << 6) |
Need to send bye after we ack?
Definition at line 727 of file chan_sip.c.
Referenced by check_pendings(), handle_response_invite(), sip_handle_t38_reinvite(), sip_hangup(), sip_read(), sip_set_rtp_peer(), and sip_set_udptl_peer().
#define SIP_PKT_DEBUG (1 << 0) |
Debug this packet
Definition at line 811 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 813 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_IGNORE_RESP (1 << 3) |
#define SIP_PKT_WITH_TOTAG (1 << 1) |
This packet has a to-tag
Definition at line 812 of file chan_sip.c.
Referenced by find_call(), and handle_request().
#define SIP_PROG_INBAND (3 << 25) |
three settings, uses two bits
Definition at line 757 of file chan_sip.c.
Referenced by handle_common_options(), sip_indicate(), and sip_show_settings().
#define SIP_PROG_INBAND_NEVER (0 << 25) |
#define SIP_PROG_INBAND_NO (1 << 25) |
Definition at line 759 of file chan_sip.c.
Referenced by handle_common_options(), and sip_show_settings().
#define SIP_PROG_INBAND_YES (2 << 25) |
Definition at line 760 of file chan_sip.c.
Referenced by handle_common_options(), and sip_indicate().
#define SIP_PROGRESS_SENT (1 << 4) |
Have sent 183 message progress
Definition at line 725 of file chan_sip.c.
Referenced by sip_indicate(), and sip_write().
#define SIP_PROMISCREDIR (1 << 8) |
Promiscuous redirection
Definition at line 729 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), parse_moved_contact(), sip_show_channel(), and sip_show_settings().
#define SIP_REALTIME (1 << 11) |
Flag for realtime users
Definition at line 732 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), parse_register_contact(), sip_destroy_peer(), sip_destroy_user(), update_call_counter(), and update_peer().
#define SIP_REINVITE (7 << 20) |
#define SIP_REINVITE_UPDATE (4 << 20) |
use UPDATE (RFC3311) when reinviting this peer
Definition at line 752 of file chan_sip.c.
Referenced by handle_common_options(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
#define SIP_RINGING (1 << 3) |
#define SIP_SENDRPID (1 << 29) |
Remote Party-ID Support
Definition at line 763 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), and initreqprep().
#define SIP_TRANS_TIMEOUT 32000 |
SIP request timeout (rfc 3261) 64*T1
Definition at line 208 of file chan_sip.c.
Referenced by sip_call(), and sip_sipredirect().
#define SIP_TRUSTRPID (1 << 9) |
Trust RPID headers?
Definition at line 730 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), and handle_common_options().
#define SIP_USECLIENTCODE (1 << 12) |
Trust X-ClientCode info message
Definition at line 733 of file chan_sip.c.
Referenced by handle_common_options(), handle_request_info(), and sip_show_settings().
#define SIP_USEREQPHONE (1 << 10) |
Add user=phone to numeric URI. Default off
Definition at line 731 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), initreqprep(), and sip_show_settings().
#define SIPBUFSIZE 512 |
Definition at line 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 843 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 844 of file chan_sip.c.
#define sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
Definition at line 845 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 482 of file chan_sip.c.
Referenced by __set_address_from_contact(), build_contact(), build_peer(), check_via(), create_addr(), initreqprep(), parse_register_contact(), set_destination(), set_peer_defaults(), sip_show_registry(), and transmit_register().
#define SUPPORTED 1 |
Define SIP option tags, used in Require: and Supported: headers We need to be aware of these properties in the phones to use the replace: header. We should not do that without knowing that the other end supports it... This is nothing we can configure, we learn by the dialog Supported: header on the REGISTER (peer) or the INVITE (other devices) We are not using many of these today, but will in the future. This is documented in RFC 3261
Definition at line 408 of file chan_sip.c.
#define SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support.
Definition at line 479 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 818 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_RATE_12000 (1 << 12) |
12000 bps t38FaxRate
Definition at line 837 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 838 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 833 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 834 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 835 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 836 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 823 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
Definition at line 822 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 820 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_TRANSCODING_MMR (1 << 1) |
Default: 0 (unset)
Definition at line 819 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_UDP_EC_FEC (1 << 4) |
Set for t38UDPFEC
Definition at line 826 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 825 of file chan_sip.c.
Referenced by add_t38_sdp(), create_addr_from_peer(), process_sdp(), and sip_alloc().
#define T38FAX_UDP_EC_REDUNDANCY (2 << 4) |
Set for t38UDPRedundancy
Definition at line 827 of file chan_sip.c.
Referenced by add_t38_sdp(), create_addr_from_peer(), process_sdp(), and sip_alloc().
#define T38FAX_VERSION (3 << 6) |
two bits, 2 values so far, up to 4 values max
Definition at line 829 of file chan_sip.c.
Referenced by add_t38_sdp().
#define T38FAX_VERSION_0 (0 << 6) |
Version 0
Definition at line 830 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define T38FAX_VERSION_1 (1 << 6) |
Version 1
Definition at line 831 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
#define TRUE 1 |
Definition at line 158 of file chan_sip.c.
#define UNLINK | ( | element, | |||
head, | |||||
prev | ) |
--- some list management macros.
Definition at line 1622 of file chan_sip.c.
Referenced by __sip_ack(), and __sip_destroy().
#define VIDEO_CODEC_MASK 0x1fc0000 |
Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO
Definition at line 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 344 of file chan_sip.c.
00344 { 00345 AUTH_SUCCESSFUL = 0, 00346 AUTH_CHALLENGE_SENT = 1, 00347 AUTH_SECRET_FAILED = -1, 00348 AUTH_USERNAME_MISMATCH = -2, 00349 AUTH_NOT_FOUND = -3, 00350 AUTH_FAKE_AUTH = -4, 00351 AUTH_UNKNOWN_DOMAIN = -5, 00352 AUTH_PEER_NOT_DYNAMIC = -6, 00353 AUTH_ACL_FAILED = -7, 00354 };
enum domain_mode |
Modes for SIP domain handling in the PBX.
SIP_DOMAIN_AUTO | This domain is auto-configured |
SIP_DOMAIN_CONFIG | This domain is from configuration |
Definition at line 684 of file chan_sip.c.
00684 { 00685 SIP_DOMAIN_AUTO, /*!< This domain is auto-configured */ 00686 SIP_DOMAIN_CONFIG, /*!< This domain is from configuration */ 00687 };
enum invitestates |
States for the INVITE transaction, not the dialog.
Definition at line 255 of file chan_sip.c.
00255 { 00256 INV_NONE = 0, /*!< No state at all, maybe not an INVITE dialog */ 00257 INV_CALLING = 1, /*!< Invite sent, no answer */ 00258 INV_PROCEEDING = 2, /*!< We got/sent 1xx message */ 00259 INV_EARLY_MEDIA = 3, /*!< We got/sent 18x message with to-tag back */ 00260 INV_COMPLETED = 4, /*!< Got final response with error. Wait for ACK, then CONFIRMED */ 00261 INV_CONFIRMED = 5, /*!< Confirmed response - we've got an ack (Incoming calls only) */ 00262 INV_TERMINATED = 6, /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done 00263 The only way out of this is a BYE from one side */ 00264 INV_CANCELLED = 7, /*!< Transaction cancelled by client or server in non-terminated state */ 00265 };
Definition at line 282 of file chan_sip.c.
00282 { 00283 PARSE_REGISTER_FAILED, 00284 PARSE_REGISTER_UPDATE, 00285 PARSE_REGISTER_QUERY, 00286 };
enum referstatus |
Parameters to know status of transfer.
Definition at line 867 of file chan_sip.c.
00867 { 00868 REFER_IDLE, /*!< No REFER is in progress */ 00869 REFER_SENT, /*!< Sent REFER to transferee */ 00870 REFER_RECEIVED, /*!< Received REFER from transferer */ 00871 REFER_CONFIRMED, /*!< Refer confirmed with a 100 TRYING */ 00872 REFER_ACCEPTED, /*!< Accepted by transferee */ 00873 REFER_RINGING, /*!< Target Ringing */ 00874 REFER_200OK, /*!< Answered by transfer target */ 00875 REFER_FAILED, /*!< REFER declined - go on */ 00876 REFER_NOAUTH /*!< We had no auth for REFER */ 00877 };
enum sip_auth_type |
Authentication types - proxy or www authentication.
Definition at line 338 of file chan_sip.c.
00338 { 00339 PROXY_AUTH, 00340 WWW_AUTH, 00341 };
enum sip_result |
Definition at line 247 of file chan_sip.c.
00247 { 00248 AST_SUCCESS = 0, 00249 AST_FAILURE = -1, 00250 };
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 313 of file chan_sip.c.
00313 { 00314 SIP_UNKNOWN, /* Unknown response */ 00315 SIP_RESPONSE, /* Not request, response to outbound request */ 00316 SIP_REGISTER, 00317 SIP_OPTIONS, 00318 SIP_NOTIFY, 00319 SIP_INVITE, 00320 SIP_ACK, 00321 SIP_PRACK, /* Not supported at all */ 00322 SIP_BYE, 00323 SIP_REFER, 00324 SIP_SUBSCRIBE, 00325 SIP_MESSAGE, 00326 SIP_UPDATE, /* We can send UPDATE; but not accept it */ 00327 SIP_INFO, 00328 SIP_CANCEL, 00329 SIP_PUBLISH, /* Not supported at all */ 00330 SIP_PING, /* Not supported at all, no standard but still implemented out there */ 00331 };
enum sipregistrystate |
States for outbound registrations (with register= lines in sip.conf.
Definition at line 357 of file chan_sip.c.
00357 { 00358 REG_STATE_UNREGISTERED = 0, /*!< We are not registered */ 00359 REG_STATE_REGSENT, /*!< Registration request sent */ 00360 REG_STATE_AUTHSENT, /*!< We have tried to authenticate */ 00361 REG_STATE_REGISTERED, /*!< Registered and done */ 00362 REG_STATE_REJECTED, /*!< Registration rejected */ 00363 REG_STATE_TIMEOUT, /*!< Registration timed out */ 00364 REG_STATE_NOAUTH, /*!< We have no accepted credentials */ 00365 REG_STATE_FAILED, /*!< Registration failed after several tries */ 00366 };
enum subscriptiontype |
Definition at line 288 of file chan_sip.c.
00288 { 00289 NONE = 0, 00290 XPIDF_XML, 00291 DIALOG_INFO_XML, 00292 CPIM_PIDF_XML, 00293 PIDF_XML, 00294 MWI_NOTIFICATION 00295 };
enum t38state |
T38 States for a call.
Definition at line 848 of file chan_sip.c.
00848 { 00849 T38_DISABLED = 0, /*!< Not enabled */ 00850 T38_LOCAL_DIRECT, /*!< Offered from local */ 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 241 of file chan_sip.c.
00241 { 00242 TRANSFER_OPENFORALL, /*!< Allow all SIP transfers */ 00243 TRANSFER_CLOSED, /*!< Allow no SIP transfers */ 00244 };
enum xmittype |
Definition at line 275 of file chan_sip.c.
00275 { 00276 XMIT_CRITICAL = 2, /*!< Transmit critical SIP message reliably, with re-transmits. 00277 If it fails, it's critical and will cause a teardown of the session */ 00278 XMIT_RELIABLE = 1, /*!< Transmit SIP message reliably, with re-transmits */ 00279 XMIT_UNRELIABLE = 0, /*!< Transmit SIP message without bothering with re-transmits */ 00280 };
static const char * __get_header | ( | const struct sip_request * | req, | |
const char * | name, | |||
int * | start | |||
) | [static] |
Definition at line 4370 of file chan_sip.c.
References ast_skip_blanks(), find_alias(), sip_request::header, sip_request::headers, and len().
04371 { 04372 int pass; 04373 04374 /* 04375 * Technically you can place arbitrary whitespace both before and after the ':' in 04376 * a header, although RFC3261 clearly says you shouldn't before, and place just 04377 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 04378 * a good idea to say you can do it, and if you can do it, why in the hell would. 04379 * you say you shouldn't. 04380 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 04381 * and we always allow spaces after that for compatibility. 04382 */ 04383 for (pass = 0; name && pass < 2;pass++) { 04384 int x, len = strlen(name); 04385 for (x=*start; x<req->headers; x++) { 04386 if (!strncasecmp(req->header[x], name, len)) { 04387 char *r = req->header[x] + len; /* skip name */ 04388 if (pedanticsipchecking) 04389 r = ast_skip_blanks(r); 04390 04391 if (*r == ':') { 04392 *start = x+1; 04393 return ast_skip_blanks(r+1); 04394 } 04395 } 04396 } 04397 if (pass == 0) /* Try aliases */ 04398 name = find_alias(name, NULL); 04399 } 04400 04401 /* Don't return NULL, so get_header is always a valid pointer */ 04402 return ""; 04403 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 19184 of file chan_sip.c.
static int __set_address_from_contact | ( | const char * | fullcontact, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 8305 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().
08306 { 08307 struct hostent *hp; 08308 struct ast_hostent ahp; 08309 int port; 08310 char *c, *host, *pt; 08311 char contact_buf[256]; 08312 char *contact; 08313 08314 /* Work on a copy */ 08315 ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf)); 08316 contact = contact_buf; 08317 08318 /* Make sure it's a SIP URL */ 08319 if (strncasecmp(contact, "sip:", 4)) { 08320 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 08321 } else 08322 contact += 4; 08323 08324 /* Ditch arguments */ 08325 /* XXX this code is replicated also shortly below */ 08326 08327 /* Grab host */ 08328 host = strchr(contact, '@'); 08329 if (!host) { /* No username part */ 08330 host = contact; 08331 c = NULL; 08332 } else { 08333 *host++ = '\0'; 08334 } 08335 pt = strchr(host, ':'); 08336 if (pt) { 08337 *pt++ = '\0'; 08338 port = atoi(pt); 08339 } else 08340 port = STANDARD_SIP_PORT; 08341 08342 contact = strsep(&contact, ";"); /* trim ; and beyond in username part */ 08343 host = strsep(&host, ";"); /* trim ; and beyond in host/domain part */ 08344 08345 /* XXX This could block for a long time XXX */ 08346 /* We should only do this if it's a name, not an IP */ 08347 hp = ast_gethostbyname(host, &ahp); 08348 if (!hp) { 08349 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 08350 return -1; 08351 } 08352 sin->sin_family = AF_INET; 08353 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 08354 sin->sin_port = htons(port); 08355 08356 return 0; 08357 }
static void __sip_ack | ( | struct sip_pvt * | p, | |
int | seqno, | |||
int | resp, | |||
int | sipmethod | |||
) | [static] |
Acknowledges receipt of a packet and stops retransmission called with p locked.
Definition at line 2176 of file chan_sip.c.
References ast_log(), ast_sched_del(), ast_test_flag, sip_pvt::callid, sip_pkt::data, DEADLOCK_AVOIDANCE, FALSE, FLAG_RESPONSE, free, sip_pvt::lock, LOG_DEBUG, sip_pkt::next, option_debug, sip_pvt::packets, sip_pvt::pendinginvite, sip_pkt::retransid, sched, sip_pkt::seqno, sip_methods, sipdebug, cfsip_methods::text, TRUE, and UNLINK.
Referenced by __sip_pretend_ack(), handle_request(), and handle_response().
02177 { 02178 struct sip_pkt *cur, *prev = NULL; 02179 02180 /* Just in case... */ 02181 char *msg; 02182 int res = FALSE; 02183 02184 msg = sip_methods[sipmethod].text; 02185 02186 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 02187 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 02188 ((ast_test_flag(cur, FLAG_RESPONSE)) || 02189 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 02190 if (!resp && (seqno == p->pendinginvite)) { 02191 if (option_debug) 02192 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 02193 p->pendinginvite = 0; 02194 } 02195 /* this is our baby */ 02196 res = TRUE; 02197 UNLINK(cur, p->packets, prev); 02198 if (cur->retransid > -1) { 02199 if (sipdebug && option_debug > 3) 02200 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 02201 } 02202 /* This odd section is designed to thwart a 02203 * race condition in the packet scheduler. There are 02204 * two conditions under which deleting the packet from the 02205 * scheduler can fail. 02206 * 02207 * 1. The packet has been removed from the scheduler because retransmission 02208 * is being attempted. The problem is that if the packet is currently attempting 02209 * retransmission and we are at this point in the code, then that MUST mean 02210 * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the 02211 * lock temporarily to allow retransmission. 02212 * 02213 * 2. The packet has reached its maximum number of retransmissions and has 02214 * been permanently removed from the packet scheduler. If this is the case, then 02215 * the packet's retransid will be set to -1. The atomicity of the setting and checking 02216 * of the retransid to -1 is ensured since in both cases p's lock is held. 02217 */ 02218 while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) { 02219 DEADLOCK_AVOIDANCE(&p->lock); 02220 } 02221 free(cur); 02222 break; 02223 } 02224 } 02225 if (option_debug) 02226 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"); 02227 }
static int __sip_autodestruct | ( | const void * | data | ) | [static] |
Kill a SIP dialog (called by scheduler).
Definition at line 2092 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup(), ast_set_flag, ast_test_flag, ASTOBJ_UNREF, sip_pvt::autokillid, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, LOG_DEBUG, LOG_WARNING, sip_pvt::method, NONE, option_debug, sip_pvt::owner, sip_pvt::packets, sip_pvt::refer, sip_pvt::relatedpeer, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_destroy(), sip_destroy_peer(), sip_methods, SIP_NEEDDESTROY, sip_scheddestroy(), sip_pvt::subscribed, transmit_request_with_auth(), transmit_state_notify(), TRUE, and XMIT_RELIABLE.
Referenced by sip_scheddestroy().
02093 { 02094 struct sip_pvt *p = (struct sip_pvt *)data; 02095 02096 /* If this is a subscription, tell the phone that we got a timeout */ 02097 if (p->subscribed) { 02098 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 02099 p->subscribed = NONE; 02100 append_history(p, "Subscribestatus", "timeout"); 02101 if (option_debug > 2) 02102 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>"); 02103 return 10000; /* Reschedule this destruction so that we know that it's gone */ 02104 } 02105 02106 /* If there are packets still waiting for delivery, delay the destruction */ 02107 /* via bug 12101, the two usages of SIP_NEEDDESTROY in the following block 02108 * of code make a sort of "safety relief valve", that allows sip channels 02109 * that were created via INVITE, then thru some sequence were CANCELED, 02110 * to die, rather than infinitely be rescheduled */ 02111 if (p->packets && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 02112 if (option_debug > 2) 02113 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>"); 02114 append_history(p, "ReliableXmit", "timeout"); 02115 if (p->method == SIP_CANCEL || p->method == SIP_BYE) { 02116 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 02117 } 02118 return 10000; 02119 } 02120 02121 /* If we're destroying a subscription, dereference peer object too */ 02122 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 02123 ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer); 02124 02125 /* Reset schedule ID */ 02126 p->autokillid = -1; 02127 02128 if (option_debug) 02129 ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid); 02130 append_history(p, "AutoDestroy", "%s", p->callid); 02131 if (p->owner) { 02132 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 02133 ast_queue_hangup(p->owner); 02134 } else if (p->refer && !ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 02135 if (option_debug > 2) 02136 ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid); 02137 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 02138 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 02139 } else 02140 sip_destroy(p); 02141 return 0; 02142 }
static int __sip_destroy | ( | struct sip_pvt * | p, | |
int | lockowner | |||
) | [static] |
Execute destruction of SIP dialog structure, release memory.
Definition at line 3134 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().
03135 { 03136 struct sip_pvt *cur, *prev = NULL; 03137 struct sip_pkt *cp; 03138 struct sip_request *req; 03139 03140 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 03141 if (p->rtp && ast_rtp_get_bridged(p->rtp)) { 03142 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03143 return -1; 03144 } 03145 03146 if (p->vrtp && ast_rtp_get_bridged(p->vrtp)) { 03147 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03148 return -1; 03149 } 03150 03151 if (sip_debug_test_pvt(p) || option_debug > 2) 03152 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03153 03154 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03155 update_call_counter(p, DEC_CALL_LIMIT); 03156 if (option_debug > 1) 03157 ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 03158 } 03159 03160 /* Unlink us from the owner if we have one */ 03161 if (p->owner) { 03162 if (lockowner) 03163 ast_channel_lock(p->owner); 03164 if (option_debug) 03165 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 03166 p->owner->tech_pvt = NULL; 03167 /* Make sure that the channel knows its backend is going away */ 03168 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03169 if (lockowner) 03170 ast_channel_unlock(p->owner); 03171 /* Give the channel a chance to react before deallocation */ 03172 usleep(1); 03173 } 03174 03175 /* Remove link from peer to subscription of MWI */ 03176 if (p->relatedpeer) { 03177 if (p->relatedpeer->mwipvt == p) { 03178 p->relatedpeer->mwipvt = NULL; 03179 } 03180 ASTOBJ_UNREF(p->relatedpeer, sip_destroy_peer); 03181 } 03182 03183 if (dumphistory) 03184 sip_dump_history(p); 03185 03186 if (p->options) 03187 free(p->options); 03188 03189 if (p->stateid > -1) 03190 ast_extension_state_del(p->stateid, NULL); 03191 AST_SCHED_DEL(sched, p->initid); 03192 AST_SCHED_DEL(sched, p->waitid); 03193 AST_SCHED_DEL(sched, p->autokillid); 03194 AST_SCHED_DEL(sched, p->request_queue_sched_id); 03195 03196 if (p->rtp) { 03197 ast_rtp_destroy(p->rtp); 03198 } 03199 if (p->vrtp) { 03200 ast_rtp_destroy(p->vrtp); 03201 } 03202 if (p->udptl) 03203 ast_udptl_destroy(p->udptl); 03204 if (p->refer) 03205 free(p->refer); 03206 if (p->route) { 03207 free_old_route(p->route); 03208 p->route = NULL; 03209 } 03210 if (p->registry) { 03211 if (p->registry->call == p) 03212 p->registry->call = NULL; 03213 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 03214 } 03215 03216 /* Clear history */ 03217 if (p->history) { 03218 struct sip_history *hist; 03219 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 03220 free(hist); 03221 p->history_entries--; 03222 } 03223 free(p->history); 03224 p->history = NULL; 03225 } 03226 03227 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 03228 ast_free(req); 03229 } 03230 03231 for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) { 03232 if (cur == p) { 03233 UNLINK(cur, iflist, prev); 03234 break; 03235 } 03236 } 03237 if (!cur) { 03238 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 03239 return 0; 03240 } 03241 03242 /* remove all current packets in this dialog */ 03243 while((cp = p->packets)) { 03244 p->packets = p->packets->next; 03245 AST_SCHED_DEL(sched, cp->retransid); 03246 free(cp); 03247 } 03248 if (p->chanvars) { 03249 ast_variables_destroy(p->chanvars); 03250 p->chanvars = NULL; 03251 } 03252 ast_mutex_destroy(&p->lock); 03253 03254 ast_string_field_free_memory(p); 03255 03256 free(p); 03257 return 0; 03258 }
static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 7731 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
07732 { 07733 int res; 07734 07735 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 07736 return res; 07737 }
static void __sip_pretend_ack | ( | struct sip_pvt * | p | ) | [static] |
Pretend to ack all packets called with p locked.
Definition at line 2231 of file chan_sip.c.
References __sip_ack(), ast_log(), ast_test_flag, sip_pkt::data, find_sip_method(), FLAG_RESPONSE, LOG_WARNING, sip_pkt::method, sip_request::method, sip_pvt::packets, sip_pkt::seqno, and sip_methods.
Referenced by handle_request_bye(), handle_request_cancel(), sip_hangup(), and sip_reg_timeout().
02232 { 02233 struct sip_pkt *cur = NULL; 02234 02235 while (p->packets) { 02236 int method; 02237 if (cur == p->packets) { 02238 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 02239 return; 02240 } 02241 cur = p->packets; 02242 method = (cur->method) ? cur->method : find_sip_method(cur->data); 02243 __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method); 02244 } 02245 }
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 2045 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().
02046 { 02047 struct sip_pkt *pkt; 02048 int siptimer_a = DEFAULT_RETRANS; 02049 int xmitres = 0; 02050 02051 if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) 02052 return AST_FAILURE; 02053 memcpy(pkt->data, data, len); 02054 pkt->method = sipmethod; 02055 pkt->packetlen = len; 02056 pkt->next = p->packets; 02057 pkt->owner = p; 02058 pkt->seqno = seqno; 02059 if (resp) 02060 ast_set_flag(pkt, FLAG_RESPONSE); 02061 pkt->data[len] = '\0'; 02062 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 02063 pkt->retransid = -1; 02064 if (fatal) 02065 ast_set_flag(pkt, FLAG_FATAL); 02066 if (pkt->timer_t1) 02067 siptimer_a = pkt->timer_t1 * 2; 02068 02069 if (option_debug > 3 && sipdebug) 02070 ast_log(LOG_DEBUG, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid); 02071 pkt->retransid = -1; 02072 pkt->next = p->packets; 02073 p->packets = pkt; 02074 if (sipmethod == SIP_INVITE) { 02075 /* Note this is a pending invite */ 02076 p->pendinginvite = seqno; 02077 } 02078 02079 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 02080 02081 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 02082 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02083 return AST_FAILURE; 02084 } else { 02085 /* Schedule retransmission */ 02086 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 02087 return AST_SUCCESS; 02088 } 02089 }
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 2248 of file chan_sip.c.
References ast_log(), AST_SCHED_DEL, ast_test_flag, sip_pvt::callid, sip_pkt::data, FLAG_RESPONSE, LOG_DEBUG, method_match(), sip_pkt::next, option_debug, sip_pvt::packets, sip_pkt::retransid, sched, sip_pkt::seqno, sip_methods, sipdebug, and cfsip_methods::text.
Referenced by handle_response().
02249 { 02250 struct sip_pkt *cur; 02251 int res = -1; 02252 02253 for (cur = p->packets; cur; cur = cur->next) { 02254 if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp && 02255 (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) { 02256 /* this is our baby */ 02257 if (cur->retransid > -1) { 02258 if (option_debug > 3 && sipdebug) 02259 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 02260 } 02261 AST_SCHED_DEL(sched, cur->retransid); 02262 res = 0; 02263 break; 02264 } 02265 } 02266 if (option_debug) 02267 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"); 02268 return res; 02269 }
static int __sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[], | |||
int | subscriptions | |||
) | [static] |
SIP show channels CLI (main function).
Definition at line 11230 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().
11231 { 11232 #define FORMAT3L "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" 11233 #define FORMAT3H "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" 11234 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" 11235 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" 11236 struct sip_pvt *cur; 11237 int numchans = 0; 11238 char *referstatus = NULL; 11239 11240 if (argc != 3) 11241 return RESULT_SHOWUSAGE; 11242 ast_mutex_lock(&iflock); 11243 cur = iflist; 11244 if (!subscriptions) 11245 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 11246 else 11247 ast_cli(fd, FORMAT3H, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry"); 11248 for (; cur; cur = cur->next) { 11249 referstatus = ""; 11250 if (cur->refer) { /* SIP transfer in progress */ 11251 referstatus = referstatus2str(cur->refer->status); 11252 } 11253 if (cur->subscribed == NONE && !subscriptions) { 11254 char formatbuf[SIPBUFSIZE/2]; 11255 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 11256 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 11257 cur->callid, 11258 cur->ocseq, cur->icseq, 11259 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 11260 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 11261 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 11262 cur->lastmsg , 11263 referstatus 11264 ); 11265 numchans++; 11266 } 11267 if (cur->subscribed != NONE && subscriptions) { 11268 ast_cli(fd, FORMAT3L, ast_inet_ntoa(cur->sa.sin_addr), 11269 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 11270 cur->callid, 11271 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 11272 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 11273 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 11274 subscription_type2str(cur->subscribed), 11275 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>", 11276 cur->expiry 11277 ); 11278 numchans++; 11279 } 11280 } 11281 ast_mutex_unlock(&iflock); 11282 if (!subscriptions) 11283 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 11284 else 11285 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 11286 return RESULT_SUCCESS; 11287 #undef FORMAT 11288 #undef FORMAT2 11289 #undef FORMAT3 11290 }
static int __sip_xmit | ( | struct sip_pvt * | p, | |
char * | data, | |||
int | len | |||
) | [static] |
Transmit SIP message.
Definition at line 1789 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().
01790 { 01791 int res; 01792 const struct sockaddr_in *dst = sip_real_dst(p); 01793 res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)); 01794 01795 if (res == -1) { 01796 switch (errno) { 01797 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 01798 case EHOSTUNREACH: /* Host can't be reached */ 01799 case ENETDOWN: /* Inteface down */ 01800 case ENETUNREACH: /* Network failure */ 01801 case ECONNREFUSED: /* ICMP port unreachable */ 01802 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 01803 } 01804 01805 if (p->registry && p->registry->regstate < REG_STATE_REGISTERED) { 01806 AST_SCHED_DEL(sched, p->registry->timeout); 01807 p->registry->needdns = TRUE; 01808 p->registry->timeout = ast_sched_add(sched, 1, sip_reg_timeout, p->registry); 01809 } 01810 } 01811 01812 if (res != len) 01813 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)); 01814 return res; 01815 }
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 6266 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().
06267 { 06268 struct sip_request resp; 06269 int seqno = 0; 06270 06271 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06272 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06273 return -1; 06274 } 06275 respprep(&resp, p, msg, req); 06276 add_header_contentLength(&resp, 0); 06277 /* If we are cancelling an incoming invite for some reason, add information 06278 about the reason why we are doing this in clear text */ 06279 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 06280 char buf[10]; 06281 06282 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 06283 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 06284 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 06285 } 06286 return send_response(p, &resp, reliable, seqno); 06287 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 19184 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 10788 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().
10789 { 10790 char status[30] = ""; 10791 char cbuf[256]; 10792 struct sip_peer *peer; 10793 char codec_buf[512]; 10794 struct ast_codec_pref *pref; 10795 struct ast_variable *v; 10796 struct sip_auth *auth; 10797 int x = 0, codec = 0, load_realtime; 10798 int realtimepeers; 10799 10800 realtimepeers = ast_check_realtime("sippeers"); 10801 10802 if (argc < 4) 10803 return RESULT_SHOWUSAGE; 10804 10805 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10806 peer = find_peer(argv[3], NULL, load_realtime, 0); 10807 if (s) { /* Manager */ 10808 if (peer) { 10809 const char *id = astman_get_header(m,"ActionID"); 10810 10811 astman_append(s, "Response: Success\r\n"); 10812 if (!ast_strlen_zero(id)) 10813 astman_append(s, "ActionID: %s\r\n",id); 10814 } else { 10815 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]); 10816 astman_send_error(s, m, cbuf); 10817 return 0; 10818 } 10819 } 10820 if (peer && type==0 ) { /* Normal listing */ 10821 ast_cli(fd,"\n\n"); 10822 ast_cli(fd, " * Name : %s\n", peer->name); 10823 if (realtimepeers) { /* Realtime is enabled */ 10824 ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 10825 } 10826 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 10827 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 10828 for (auth = peer->auth; auth; auth = auth->next) { 10829 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 10830 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 10831 } 10832 ast_cli(fd, " Context : %s\n", peer->context); 10833 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 10834 ast_cli(fd, " Language : %s\n", peer->language); 10835 if (!ast_strlen_zero(peer->accountcode)) 10836 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 10837 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 10838 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 10839 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 10840 if (!ast_strlen_zero(peer->fromuser)) 10841 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 10842 if (!ast_strlen_zero(peer->fromdomain)) 10843 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 10844 ast_cli(fd, " Callgroup : "); 10845 print_group(fd, peer->callgroup, 0); 10846 ast_cli(fd, " Pickupgroup : "); 10847 print_group(fd, peer->pickupgroup, 0); 10848 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 10849 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 10850 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 10851 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 10852 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 10853 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 10854 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 10855 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 10856 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))); 10857 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10858 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 10859 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 10860 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10861 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 10862 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 10863 #endif 10864 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 10865 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 10866 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 10867 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 10868 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 10869 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 10870 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10871 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10872 10873 /* - is enumerated */ 10874 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10875 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 10876 ast_cli(fd, " ToHost : %s\n", peer->tohost); 10877 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)); 10878 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 10879 if (!ast_strlen_zero(global_regcontext)) 10880 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 10881 ast_cli(fd, " Def. Username: %s\n", peer->username); 10882 ast_cli(fd, " SIP Options : "); 10883 if (peer->sipoptions) { 10884 int lastoption = -1; 10885 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10886 if (sip_options[x].id != lastoption) { 10887 if (peer->sipoptions & sip_options[x].id) 10888 ast_cli(fd, "%s ", sip_options[x].text); 10889 lastoption = x; 10890 } 10891 } 10892 } else 10893 ast_cli(fd, "(none)"); 10894 10895 ast_cli(fd, "\n"); 10896 ast_cli(fd, " Codecs : "); 10897 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10898 ast_cli(fd, "%s\n", codec_buf); 10899 ast_cli(fd, " Codec Order : ("); 10900 print_codec_to_cli(fd, &peer->prefs); 10901 ast_cli(fd, ")\n"); 10902 10903 ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No"); 10904 ast_cli(fd, " Status : "); 10905 peer_status(peer, status, sizeof(status)); 10906 ast_cli(fd, "%s\n",status); 10907 ast_cli(fd, " Useragent : %s\n", peer->useragent); 10908 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 10909 if (peer->chanvars) { 10910 ast_cli(fd, " Variables :\n"); 10911 for (v = peer->chanvars ; v ; v = v->next) 10912 ast_cli(fd, " %s = %s\n", v->name, v->value); 10913 } 10914 ast_cli(fd,"\n"); 10915 ASTOBJ_UNREF(peer,sip_destroy_peer); 10916 } else if (peer && type == 1) { /* manager listing */ 10917 char buf[256]; 10918 astman_append(s, "Channeltype: SIP\r\n"); 10919 astman_append(s, "ObjectName: %s\r\n", peer->name); 10920 astman_append(s, "ChanObjectType: peer\r\n"); 10921 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 10922 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 10923 astman_append(s, "Context: %s\r\n", peer->context); 10924 astman_append(s, "Language: %s\r\n", peer->language); 10925 if (!ast_strlen_zero(peer->accountcode)) 10926 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 10927 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 10928 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 10929 if (!ast_strlen_zero(peer->fromuser)) 10930 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 10931 if (!ast_strlen_zero(peer->fromdomain)) 10932 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 10933 astman_append(s, "Callgroup: "); 10934 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup)); 10935 astman_append(s, "Pickupgroup: "); 10936 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup)); 10937 astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox); 10938 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 10939 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 10940 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 10941 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 10942 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 10943 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 10944 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 10945 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))); 10946 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10947 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 10948 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 10949 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 10950 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 10951 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 10952 10953 /* - is enumerated */ 10954 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10955 astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg); 10956 astman_append(s, "ToHost: %s\r\n", peer->tohost); 10957 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)); 10958 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)); 10959 astman_append(s, "Default-Username: %s\r\n", peer->username); 10960 if (!ast_strlen_zero(global_regcontext)) 10961 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 10962 astman_append(s, "Codecs: "); 10963 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10964 astman_append(s, "%s\r\n", codec_buf); 10965 astman_append(s, "CodecOrder: "); 10966 pref = &peer->prefs; 10967 for(x = 0; x < 32 ; x++) { 10968 codec = ast_codec_pref_index(pref,x); 10969 if (!codec) 10970 break; 10971 astman_append(s, "%s", ast_getformatname(codec)); 10972 if (x < 31 && ast_codec_pref_index(pref,x+1)) 10973 astman_append(s, ","); 10974 } 10975 10976 astman_append(s, "\r\n"); 10977 astman_append(s, "Status: "); 10978 peer_status(peer, status, sizeof(status)); 10979 astman_append(s, "%s\r\n", status); 10980 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 10981 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 10982 if (peer->chanvars) { 10983 for (v = peer->chanvars ; v ; v = v->next) { 10984 astman_append(s, "ChanVariable:\n"); 10985 astman_append(s, " %s,%s\r\n", v->name, v->value); 10986 } 10987 } 10988 10989 ASTOBJ_UNREF(peer,sip_destroy_peer); 10990 10991 } else { 10992 ast_cli(fd,"Peer %s not found.\n", argv[3]); 10993 ast_cli(fd,"\n"); 10994 } 10995 10996 return RESULT_SUCCESS; 10997 }
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 10338 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().
10339 { 10340 regex_t regexbuf; 10341 int havepattern = FALSE; 10342 10343 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 10344 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 10345 10346 char name[256]; 10347 int total_peers = 0; 10348 int peers_mon_online = 0; 10349 int peers_mon_offline = 0; 10350 int peers_unmon_offline = 0; 10351 int peers_unmon_online = 0; 10352 const char *id; 10353 char idtext[256] = ""; 10354 int realtimepeers; 10355 10356 realtimepeers = ast_check_realtime("sippeers"); 10357 10358 if (s) { /* Manager - get ActionID */ 10359 id = astman_get_header(m,"ActionID"); 10360 if (!ast_strlen_zero(id)) 10361 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 10362 } 10363 10364 switch (argc) { 10365 case 5: 10366 if (!strcasecmp(argv[3], "like")) { 10367 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 10368 return RESULT_SHOWUSAGE; 10369 havepattern = TRUE; 10370 } else 10371 return RESULT_SHOWUSAGE; 10372 case 3: 10373 break; 10374 default: 10375 return RESULT_SHOWUSAGE; 10376 } 10377 10378 if (!s) /* Normal list */ 10379 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 10380 10381 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10382 char status[20] = ""; 10383 char srch[2000]; 10384 char pstatus; 10385 10386 ASTOBJ_RDLOCK(iterator); 10387 10388 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10389 ASTOBJ_UNLOCK(iterator); 10390 continue; 10391 } 10392 10393 if (!ast_strlen_zero(iterator->username) && !s) 10394 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 10395 else 10396 ast_copy_string(name, iterator->name, sizeof(name)); 10397 10398 pstatus = peer_status(iterator, status, sizeof(status)); 10399 if (pstatus == 1) 10400 peers_mon_online++; 10401 else if (pstatus == 0) 10402 peers_mon_offline++; 10403 else { 10404 if (iterator->addr.sin_port == 0) 10405 peers_unmon_offline++; 10406 else 10407 peers_unmon_online++; 10408 } 10409 10410 snprintf(srch, sizeof(srch), FORMAT, name, 10411 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10412 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10413 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10414 iterator->ha ? " A " : " ", /* permit/deny */ 10415 ntohs(iterator->addr.sin_port), status, 10416 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10417 10418 if (!s) {/* Normal CLI list */ 10419 ast_cli(fd, FORMAT, name, 10420 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10421 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10422 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10423 iterator->ha ? " A " : " ", /* permit/deny */ 10424 10425 ntohs(iterator->addr.sin_port), status, 10426 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10427 } else { /* Manager format */ 10428 /* The names here need to be the same as other channels */ 10429 astman_append(s, 10430 "Event: PeerEntry\r\n%s" 10431 "Channeltype: SIP\r\n" 10432 "ObjectName: %s\r\n" 10433 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 10434 "IPaddress: %s\r\n" 10435 "IPport: %d\r\n" 10436 "Dynamic: %s\r\n" 10437 "Natsupport: %s\r\n" 10438 "VideoSupport: %s\r\n" 10439 "ACL: %s\r\n" 10440 "Status: %s\r\n" 10441 "RealtimeDevice: %s\r\n\r\n", 10442 idtext, 10443 iterator->name, 10444 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 10445 ntohs(iterator->addr.sin_port), 10446 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 10447 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 10448 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 10449 iterator->ha ? "yes" : "no", /* permit/deny */ 10450 status, 10451 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 10452 } 10453 10454 ASTOBJ_UNLOCK(iterator); 10455 10456 total_peers++; 10457 } while(0) ); 10458 10459 if (!s) 10460 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 10461 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 10462 10463 if (havepattern) 10464 regfree(®exbuf); 10465 10466 if (total) 10467 *total = total_peers; 10468 10469 10470 return RESULT_SUCCESS; 10471 #undef FORMAT 10472 #undef FORMAT2 10473 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 15492 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.
15493 { 15494 struct ast_rtp_quality qos; 15495 struct sip_pvt *p = chan->tech_pvt; 15496 char *all = "", *parse = ast_strdupa(preparse); 15497 AST_DECLARE_APP_ARGS(args, 15498 AST_APP_ARG(param); 15499 AST_APP_ARG(type); 15500 AST_APP_ARG(field); 15501 ); 15502 AST_STANDARD_APP_ARGS(args, parse); 15503 15504 /* Sanity check */ 15505 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 15506 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 15507 return 0; 15508 } 15509 15510 if (strcasecmp(args.param, "rtpqos")) 15511 return 0; 15512 15513 /* Default arguments of audio,all */ 15514 if (ast_strlen_zero(args.type)) 15515 args.type = "audio"; 15516 if (ast_strlen_zero(args.field)) 15517 args.field = "all"; 15518 15519 memset(buf, 0, buflen); 15520 memset(&qos, 0, sizeof(qos)); 15521 15522 if (strcasecmp(args.type, "AUDIO") == 0) { 15523 all = ast_rtp_get_quality(p->rtp, &qos); 15524 } else if (strcasecmp(args.type, "VIDEO") == 0) { 15525 all = ast_rtp_get_quality(p->vrtp, &qos); 15526 } 15527 15528 if (strcasecmp(args.field, "local_ssrc") == 0) 15529 snprintf(buf, buflen, "%u", qos.local_ssrc); 15530 else if (strcasecmp(args.field, "local_lostpackets") == 0) 15531 snprintf(buf, buflen, "%u", qos.local_lostpackets); 15532 else if (strcasecmp(args.field, "local_jitter") == 0) 15533 snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0); 15534 else if (strcasecmp(args.field, "local_count") == 0) 15535 snprintf(buf, buflen, "%u", qos.local_count); 15536 else if (strcasecmp(args.field, "remote_ssrc") == 0) 15537 snprintf(buf, buflen, "%u", qos.remote_ssrc); 15538 else if (strcasecmp(args.field, "remote_lostpackets") == 0) 15539 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 15540 else if (strcasecmp(args.field, "remote_jitter") == 0) 15541 snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0); 15542 else if (strcasecmp(args.field, "remote_count") == 0) 15543 snprintf(buf, buflen, "%u", qos.remote_count); 15544 else if (strcasecmp(args.field, "rtt") == 0) 15545 snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0); 15546 else if (strcasecmp(args.field, "all") == 0) 15547 ast_copy_string(buf, all, buflen); 15548 else { 15549 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 15550 return -1; 15551 } 15552 return 0; 15553 }
static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 2282 of file chan_sip.c.
References sip_request::data, sip_request::len, and sip_request::lines.
Referenced by send_request(), and send_response().
02283 { 02284 if (!req->lines) { 02285 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 02286 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 02287 req->len += strlen(req->data + req->len); 02288 } 02289 }
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 6471 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().
06474 { 06475 int rtp_code; 06476 struct ast_format_list fmt; 06477 06478 06479 if (debug) 06480 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 06481 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 06482 return; 06483 06484 if (p->rtp) { 06485 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 06486 fmt = ast_codec_pref_getsize(pref, codec); 06487 } 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 */ 06488 return; 06489 ast_build_string(m_buf, m_size, " %d", rtp_code); 06490 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06491 ast_rtp_lookup_mime_subtype(1, codec, 06492 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 06493 sample_rate); 06494 if (codec == AST_FORMAT_G729A) { 06495 /* Indicate that we don't support VAD (G.729 annex B) */ 06496 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 06497 } else if (codec == AST_FORMAT_G723_1) { 06498 /* Indicate that we don't support VAD (G.723.1 annex A) */ 06499 ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code); 06500 } else if (codec == AST_FORMAT_ILBC) { 06501 /* Add information about us using only 20/30 ms packetization */ 06502 ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 06503 } 06504 06505 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 06506 *min_packet_size = fmt.cur_ms; 06507 06508 /* Our first codec packetization processed cannot be less than zero */ 06509 if ((*min_packet_size) == 0 && fmt.cur_ms) 06510 *min_packet_size = fmt.cur_ms; 06511 }
static int add_digit | ( | struct sip_request * | req, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Add DTMF INFO tone to sip message.
Definition at line 6439 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_digit().
06440 { 06441 char tmp[256]; 06442 06443 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 06444 add_header(req, "Content-Type", "application/dtmf-relay"); 06445 add_header_contentLength(req, strlen(tmp)); 06446 add_line(req, tmp); 06447 return 0; 06448 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 5770 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.
05771 { 05772 int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */ 05773 05774 if (req->headers == SIP_MAX_HEADERS) { 05775 ast_log(LOG_WARNING, "Out of SIP header space\n"); 05776 return -1; 05777 } 05778 05779 if (req->lines) { 05780 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 05781 return -1; 05782 } 05783 05784 if (maxlen <= 0) { 05785 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 05786 return -1; 05787 } 05788 05789 req->header[req->headers] = req->data + req->len; 05790 05791 if (compactheaders) 05792 var = find_alias(var, var); 05793 05794 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 05795 req->len += strlen(req->header[req->headers]); 05796 req->headers++; 05797 05798 return 0; 05799 }
static int add_header_contentLength | ( | struct sip_request * | req, | |
int | len | |||
) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 5802 of file chan_sip.c.
References add_header().
Referenced by __transmit_response(), add_digit(), add_sdp(), add_t38_sdp(), add_text(), add_vidupdate(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_request(), transmit_request_with_auth(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), transmit_response_with_unsupported(), and transmit_state_notify().
05803 { 05804 char clen[10]; 05805 05806 snprintf(clen, sizeof(clen), "%d", len); 05807 return add_header(req, "Content-Length", clen); 05808 }
static int add_line | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 5811 of file chan_sip.c.
References ast_log(), sip_request::data, sip_request::len, sip_request::line, sip_request::lines, and SIP_MAX_LINES.
05812 { 05813 if (req->lines == SIP_MAX_LINES) { 05814 ast_log(LOG_WARNING, "Out of SIP line space\n"); 05815 return -1; 05816 } 05817 if (!req->lines) { 05818 /* Add extra empty return */ 05819 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 05820 req->len += strlen(req->data + req->len); 05821 } 05822 if (req->len >= sizeof(req->data) - 4) { 05823 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 05824 return -1; 05825 } 05826 req->line[req->lines] = req->data + req->len; 05827 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 05828 req->len += strlen(req->line[req->lines]); 05829 req->lines++; 05830 return 0; 05831 }
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 6650 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().
06653 { 06654 int rtp_code; 06655 06656 if (debug) 06657 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 06658 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 06659 return; 06660 06661 ast_build_string(m_buf, m_size, " %d", rtp_code); 06662 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06663 ast_rtp_lookup_mime_subtype(0, format, 0), 06664 sample_rate); 06665 if (format == AST_RTP_DTMF) 06666 /* Indicate we support DTMF and FLASH... */ 06667 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 06668 }
static struct sip_auth * add_realm_authentication | ( | struct sip_auth * | authlist, | |
char * | configuration, | |||
int | lineno | |||
) | [static] |
Add realm authentication in list.
Definition at line 17228 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().
17229 { 17230 char authcopy[256]; 17231 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 17232 char *stringp; 17233 struct sip_auth *a, *b, *auth; 17234 17235 if (ast_strlen_zero(configuration)) 17236 return authlist; 17237 17238 if (option_debug) 17239 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 17240 17241 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 17242 stringp = authcopy; 17243 17244 username = stringp; 17245 realm = strrchr(stringp, '@'); 17246 if (realm) 17247 *realm++ = '\0'; 17248 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 17249 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 17250 return authlist; 17251 } 17252 stringp = username; 17253 username = strsep(&stringp, ":"); 17254 if (username) { 17255 secret = strsep(&stringp, ":"); 17256 if (!secret) { 17257 stringp = username; 17258 md5secret = strsep(&stringp,"#"); 17259 } 17260 } 17261 if (!(auth = ast_calloc(1, sizeof(*auth)))) 17262 return authlist; 17263 17264 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 17265 ast_copy_string(auth->username, username, sizeof(auth->username)); 17266 if (secret) 17267 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 17268 if (md5secret) 17269 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 17270 17271 /* find the end of the list */ 17272 for (b = NULL, a = authlist; a ; b = a, a = a->next) 17273 ; 17274 if (b) 17275 b->next = auth; /* Add structure add end of list */ 17276 else 17277 authlist = auth; 17278 17279 if (option_verbose > 2) 17280 ast_verbose("Added authentication for realm %s\n", realm); 17281 17282 return authlist; 17283 17284 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 5932 of file chan_sip.c.
References add_header(), ast_copy_string(), sip_route::hop, sip_route::next, and SIPBUFSIZE.
Referenced by reqprep().
05933 { 05934 char r[SIPBUFSIZE*2], *p; 05935 int n, rem = sizeof(r); 05936 05937 if (!route) 05938 return; 05939 05940 p = r; 05941 for (;route ; route = route->next) { 05942 n = strlen(route->hop); 05943 if (rem < n+3) /* we need room for ",<route>" */ 05944 break; 05945 if (p != r) { /* add a separator after fist route */ 05946 *p++ = ','; 05947 --rem; 05948 } 05949 *p++ = '<'; 05950 ast_copy_string(p, route->hop, rem); /* cannot fail */ 05951 p += n; 05952 *p++ = '>'; 05953 rem -= (n+2); 05954 } 05955 *p = '\0'; 05956 add_header(req, "Route", r); 05957 }
static enum sip_result add_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add Session Description Protocol message.
Definition at line 6678 of file chan_sip.c.
References add_codec_to_sdp(), add_header(), add_header_contentLength(), add_line(), add_noncodec_to_sdp(), ast_build_string(), ast_codec_pref_index(), AST_FAILURE, AST_FORMAT_AUDIO_MASK, AST_FORMAT_MAX_AUDIO, AST_FORMAT_MAX_VIDEO, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_inet_ntoa(), ast_internal_timing_enabled(), ast_log(), ast_rtp_get_us(), AST_RTP_MAX, AST_SUCCESS, ast_test_flag, ast_verbose(), capability, debug, FALSE, sip_pvt::flags, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len(), LOG_DEBUG, sip_pvt::maxcallbitrate, option_debug, sip_pvt::ourip, sip_pvt::owner, sip_pvt::prefcodec, sip_pvt::prefs, sip_pvt::redirip, sip_pvt::rtp, SDP_SAMPLE_RATE, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, SIP_PAGE2_T38SUPPORT_RTP, SIPBUFSIZE, sip_pvt::t38, t38properties::t38support, TRUE, sip_pvt::vredirip, and sip_pvt::vrtp.
06679 { 06680 int len = 0; 06681 int alreadysent = 0; 06682 06683 struct sockaddr_in sin; 06684 struct sockaddr_in vsin; 06685 struct sockaddr_in dest; 06686 struct sockaddr_in vdest = { 0, }; 06687 06688 /* SDP fields */ 06689 char *version = "v=0\r\n"; /* Protocol version */ 06690 char *subject = "s=session\r\n"; /* Subject of the session */ 06691 char owner[256]; /* Session owner/creator */ 06692 char connection[256]; /* Connection data */ 06693 char *stime = "t=0 0\r\n"; /* Time the session is active */ 06694 char bandwidth[256] = ""; /* Max bitrate */ 06695 char *hold; 06696 char m_audio[256]; /* Media declaration line for audio */ 06697 char m_video[256]; /* Media declaration line for video */ 06698 char a_audio[1024]; /* Attributes for audio */ 06699 char a_video[1024]; /* Attributes for video */ 06700 char *m_audio_next = m_audio; 06701 char *m_video_next = m_video; 06702 size_t m_audio_left = sizeof(m_audio); 06703 size_t m_video_left = sizeof(m_video); 06704 char *a_audio_next = a_audio; 06705 char *a_video_next = a_video; 06706 size_t a_audio_left = sizeof(a_audio); 06707 size_t a_video_left = sizeof(a_video); 06708 06709 int x; 06710 int capability; 06711 int needvideo = FALSE; 06712 int debug = sip_debug_test_pvt(p); 06713 int min_audio_packet_size = 0; 06714 int min_video_packet_size = 0; 06715 06716 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 06717 06718 if (!p->rtp) { 06719 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 06720 return AST_FAILURE; 06721 } 06722 06723 /* Set RTP Session ID and version */ 06724 if (!p->sessionid) { 06725 p->sessionid = getpid(); 06726 p->sessionversion = p->sessionid; 06727 } else 06728 p->sessionversion++; 06729 06730 /* Get our addresses */ 06731 ast_rtp_get_us(p->rtp, &sin); 06732 if (p->vrtp) 06733 ast_rtp_get_us(p->vrtp, &vsin); 06734 06735 /* Is this a re-invite to move the media out, then use the original offer from caller */ 06736 if (p->redirip.sin_addr.s_addr) { 06737 dest.sin_port = p->redirip.sin_port; 06738 dest.sin_addr = p->redirip.sin_addr; 06739 } else { 06740 dest.sin_addr = p->ourip; 06741 dest.sin_port = sin.sin_port; 06742 } 06743 06744 capability = p->jointcapability; 06745 06746 06747 if (option_debug > 1) { 06748 char codecbuf[SIPBUFSIZE]; 06749 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"); 06750 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 06751 } 06752 06753 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 06754 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 06755 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 06756 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 06757 } 06758 #endif 06759 06760 /* Check if we need video in this call */ 06761 if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 06762 if (p->vrtp) { 06763 needvideo = TRUE; 06764 if (option_debug > 1) 06765 ast_log(LOG_DEBUG, "This call needs video offers!\n"); 06766 } else if (option_debug > 1) 06767 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n"); 06768 } 06769 06770 06771 /* Ok, we need video. Let's add what we need for video and set codecs. 06772 Video is handled differently than audio since we can not transcode. */ 06773 if (needvideo) { 06774 /* Determine video destination */ 06775 if (p->vredirip.sin_addr.s_addr) { 06776 vdest.sin_addr = p->vredirip.sin_addr; 06777 vdest.sin_port = p->vredirip.sin_port; 06778 } else { 06779 vdest.sin_addr = p->ourip; 06780 vdest.sin_port = vsin.sin_port; 06781 } 06782 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 06783 06784 /* Build max bitrate string */ 06785 if (p->maxcallbitrate) 06786 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 06787 if (debug) 06788 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 06789 } 06790 06791 if (debug) 06792 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 06793 06794 /* Start building generic SDP headers */ 06795 06796 /* We break with the "recommendation" and send our IP, in order that our 06797 peer doesn't have to ast_gethostbyname() us */ 06798 06799 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 06800 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 06801 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 06802 06803 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) 06804 hold = "a=recvonly\r\n"; 06805 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) 06806 hold = "a=inactive\r\n"; 06807 else 06808 hold = "a=sendrecv\r\n"; 06809 06810 /* Now, start adding audio codecs. These are added in this order: 06811 - First what was requested by the calling channel 06812 - Then preferences in order from sip.conf device config for this peer/user 06813 - Then other codecs in capabilities, including video 06814 */ 06815 06816 /* Prefer the audio codec we were requested to use, first, no matter what 06817 Note that p->prefcodec can include video codecs, so mask them out 06818 */ 06819 if (capability & p->prefcodec) { 06820 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 06821 06822 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06823 &m_audio_next, &m_audio_left, 06824 &a_audio_next, &a_audio_left, 06825 debug, &min_audio_packet_size); 06826 alreadysent |= codec; 06827 } 06828 06829 /* Start by sending our preferred audio codecs */ 06830 for (x = 0; x < 32; x++) { 06831 int codec; 06832 06833 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 06834 break; 06835 06836 if (!(capability & codec)) 06837 continue; 06838 06839 if (alreadysent & codec) 06840 continue; 06841 06842 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06843 &m_audio_next, &m_audio_left, 06844 &a_audio_next, &a_audio_left, 06845 debug, &min_audio_packet_size); 06846 alreadysent |= codec; 06847 } 06848 06849 /* Now send any other common audio and video codecs, and non-codec formats: */ 06850 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 06851 if (!(capability & x)) /* Codec not requested */ 06852 continue; 06853 06854 if (alreadysent & x) /* Already added to SDP */ 06855 continue; 06856 06857 if (x <= AST_FORMAT_MAX_AUDIO) 06858 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 06859 &m_audio_next, &m_audio_left, 06860 &a_audio_next, &a_audio_left, 06861 debug, &min_audio_packet_size); 06862 else 06863 add_codec_to_sdp(p, x, 90000, 06864 &m_video_next, &m_video_left, 06865 &a_video_next, &a_video_left, 06866 debug, &min_video_packet_size); 06867 } 06868 06869 /* Now add DTMF RFC2833 telephony-event as a codec */ 06870 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 06871 if (!(p->jointnoncodeccapability & x)) 06872 continue; 06873 06874 add_noncodec_to_sdp(p, x, 8000, 06875 &m_audio_next, &m_audio_left, 06876 &a_audio_next, &a_audio_left, 06877 debug); 06878 } 06879 06880 if (option_debug > 2) 06881 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 06882 06883 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 06884 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 06885 06886 if (min_audio_packet_size) 06887 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 06888 06889 if (min_video_packet_size) 06890 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 06891 06892 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 06893 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 06894 06895 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 06896 if (needvideo) 06897 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 06898 06899 len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold); 06900 if (needvideo) /* only if video response is appropriate */ 06901 len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold); 06902 06903 add_header(resp, "Content-Type", "application/sdp"); 06904 add_header_contentLength(resp, len); 06905 add_line(resp, version); 06906 add_line(resp, owner); 06907 add_line(resp, subject); 06908 add_line(resp, connection); 06909 if (needvideo) /* only if video response is appropriate */ 06910 add_line(resp, bandwidth); 06911 add_line(resp, stime); 06912 add_line(resp, m_audio); 06913 add_line(resp, a_audio); 06914 add_line(resp, hold); 06915 if (needvideo) { /* only if video response is appropriate */ 06916 add_line(resp, m_video); 06917 add_line(resp, a_video); 06918 add_line(resp, hold); /* Repeat hold for the video stream */ 06919 } 06920 06921 /* Update lastrtprx when we send our SDP */ 06922 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 06923 06924 if (option_debug > 2) { 06925 char buf[SIPBUFSIZE]; 06926 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability)); 06927 } 06928 06929 return AST_SUCCESS; 06930 }
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 17164 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.
17165 { 17166 struct domain *d; 17167 17168 if (ast_strlen_zero(domain)) { 17169 ast_log(LOG_WARNING, "Zero length domain.\n"); 17170 return 1; 17171 } 17172 17173 if (!(d = ast_calloc(1, sizeof(*d)))) 17174 return 0; 17175 17176 ast_copy_string(d->domain, domain, sizeof(d->domain)); 17177 17178 if (!ast_strlen_zero(context)) 17179 ast_copy_string(d->context, context, sizeof(d->context)); 17180 17181 d->mode = mode; 17182 17183 AST_LIST_LOCK(&domain_list); 17184 AST_LIST_INSERT_TAIL(&domain_list, d, list); 17185 AST_LIST_UNLOCK(&domain_list); 17186 17187 if (sipdebug) 17188 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 17189 17190 return 1; 17191 }
static int add_t38_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add T.38 Session Description Protocol message.
Definition at line 6550 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_udptl_get_local_max_datagram(), ast_udptl_get_us(), t38properties::capability, debug, t38properties::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len(), LOG_DEBUG, sip_pvt::ourip, t38properties::peercapability, s, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), t, sip_pvt::t38, t38_get_rate(), T38FAX_FILL_BIT_REMOVAL, T38FAX_RATE_MANAGEMENT_LOCAL_TCF, T38FAX_TRANSCODING_JBIG, T38FAX_TRANSCODING_MMR, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, T38FAX_VERSION, T38FAX_VERSION_0, T38FAX_VERSION_1, sip_pvt::udptl, and sip_pvt::udptlredirip.
Referenced by transmit_invite(), transmit_reinvite_with_t38_sdp(), and transmit_response_with_t38_sdp().
06551 { 06552 int len = 0; 06553 int x = 0; 06554 struct sockaddr_in udptlsin; 06555 char v[256] = ""; 06556 char s[256] = ""; 06557 char o[256] = ""; 06558 char c[256] = ""; 06559 char t[256] = ""; 06560 char m_modem[256]; 06561 char a_modem[1024]; 06562 char *m_modem_next = m_modem; 06563 size_t m_modem_left = sizeof(m_modem); 06564 char *a_modem_next = a_modem; 06565 size_t a_modem_left = sizeof(a_modem); 06566 struct sockaddr_in udptldest = { 0, }; 06567 int debug; 06568 06569 debug = sip_debug_test_pvt(p); 06570 len = 0; 06571 if (!p->udptl) { 06572 ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n"); 06573 return -1; 06574 } 06575 06576 if (!p->sessionid) { 06577 p->sessionid = getpid(); 06578 p->sessionversion = p->sessionid; 06579 } else 06580 p->sessionversion++; 06581 06582 /* Our T.38 end is */ 06583 ast_udptl_get_us(p->udptl, &udptlsin); 06584 06585 /* Determine T.38 UDPTL destination */ 06586 if (p->udptlredirip.sin_addr.s_addr) { 06587 udptldest.sin_port = p->udptlredirip.sin_port; 06588 udptldest.sin_addr = p->udptlredirip.sin_addr; 06589 } else { 06590 udptldest.sin_addr = p->ourip; 06591 udptldest.sin_port = udptlsin.sin_port; 06592 } 06593 06594 if (debug) 06595 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 06596 06597 /* We break with the "recommendation" and send our IP, in order that our 06598 peer doesn't have to ast_gethostbyname() us */ 06599 06600 if (debug) { 06601 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 06602 p->t38.capability, 06603 p->t38.peercapability, 06604 p->t38.jointcapability); 06605 } 06606 snprintf(v, sizeof(v), "v=0\r\n"); 06607 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr)); 06608 snprintf(s, sizeof(s), "s=session\r\n"); 06609 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr)); 06610 snprintf(t, sizeof(t), "t=0 0\r\n"); 06611 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 06612 06613 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 06614 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 06615 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 06616 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 06617 if ((x = t38_get_rate(p->t38.jointcapability))) 06618 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 06619 if ((p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) == T38FAX_FILL_BIT_REMOVAL) 06620 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval\r\n"); 06621 if ((p->t38.jointcapability & T38FAX_TRANSCODING_MMR) == T38FAX_TRANSCODING_MMR) 06622 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR\r\n"); 06623 if ((p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) == T38FAX_TRANSCODING_JBIG) 06624 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG\r\n"); 06625 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 06626 x = ast_udptl_get_local_max_datagram(p->udptl); 06627 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 06628 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 06629 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 06630 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 06631 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem); 06632 add_header(resp, "Content-Type", "application/sdp"); 06633 add_header_contentLength(resp, len); 06634 add_line(resp, v); 06635 add_line(resp, o); 06636 add_line(resp, s); 06637 add_line(resp, c); 06638 add_line(resp, t); 06639 add_line(resp, m_modem); 06640 add_line(resp, a_modem); 06641 06642 /* Update lastrtprx when we send our SDP */ 06643 p->lastrtprx = p->lastrtptx = time(NULL); 06644 06645 return 0; 06646 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 6428 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_message_with_text().
06429 { 06430 /* XXX Convert \n's to \r\n's XXX */ 06431 add_header(req, "Content-Type", "text/plain"); 06432 add_header_contentLength(req, strlen(text)); 06433 add_line(req, text); 06434 return 0; 06435 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 6452 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_vidupdate().
06453 { 06454 const char *xml_is_a_huge_waste_of_space = 06455 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 06456 " <media_control>\r\n" 06457 " <vc_primitive>\r\n" 06458 " <to_encoder>\r\n" 06459 " <picture_fast_update>\r\n" 06460 " </picture_fast_update>\r\n" 06461 " </to_encoder>\r\n" 06462 " </vc_primitive>\r\n" 06463 " </media_control>\r\n"; 06464 add_header(req, "Content-Type", "application/media_control+xml"); 06465 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 06466 add_line(req, xml_is_a_huge_waste_of_space); 06467 return 0; 06468 }
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 6375 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().
06376 { 06377 char tmpdat[256]; 06378 struct tm tm; 06379 time_t t = time(NULL); 06380 06381 gmtime_r(&t, &tm); 06382 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 06383 add_header(req, "Date", tmpdat); 06384 }
static void append_history_full | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1902 of file chan_sip.c.
References append_history_va(), ast_test_flag, sip_pvt::flags, and SIP_NO_HISTORY.
01903 { 01904 va_list ap; 01905 01906 if (!p) 01907 return; 01908 01909 if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY) 01910 && !recordhistory && !dumphistory) { 01911 return; 01912 } 01913 01914 va_start(ap, fmt); 01915 append_history_va(p, fmt, ap); 01916 va_end(ap); 01917 01918 return; 01919 }
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 1875 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().
01876 { 01877 char buf[80], *c = buf; /* max history length */ 01878 struct sip_history *hist; 01879 int l; 01880 01881 vsnprintf(buf, sizeof(buf), fmt, ap); 01882 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 01883 l = strlen(buf) + 1; 01884 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) 01885 return; 01886 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 01887 free(hist); 01888 return; 01889 } 01890 memcpy(hist->event, buf, l); 01891 if (p->history_entries == MAX_HISTORY_ENTRIES) { 01892 struct sip_history *oldest; 01893 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 01894 p->history_entries--; 01895 free(oldest); 01896 } 01897 AST_LIST_INSERT_TAIL(p->history, hist, list); 01898 p->history_entries++; 01899 }
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 13717 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().
13718 { 13719 if (chan && chan->_state == AST_STATE_UP) { 13720 if (ast_test_flag(chan, AST_FLAG_MOH)) 13721 ast_moh_stop(chan); 13722 else if (chan->generatordata) 13723 ast_deactivate_generator(chan); 13724 } 13725 }
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 1835 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().
01836 { 01837 struct sockaddr_in theirs, ours; 01838 01839 /* Get our local information */ 01840 ast_ouraddrfor(them, us); 01841 theirs.sin_addr = *them; 01842 ours.sin_addr = *us; 01843 01844 if (localaddr && externip.sin_addr.s_addr && 01845 (ast_apply_ha(localaddr, &theirs)) && 01846 (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) { 01847 if (externexpire && time(NULL) >= externexpire) { 01848 struct ast_hostent ahp; 01849 struct hostent *hp; 01850 01851 externexpire = time(NULL) + externrefresh; 01852 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01853 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01854 } else 01855 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01856 } 01857 *us = externip.sin_addr; 01858 if (option_debug) { 01859 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 01860 ast_inet_ntoa(*(struct in_addr *)&them->s_addr)); 01861 } 01862 } else if (bindaddr.sin_addr.s_addr) 01863 *us = bindaddr.sin_addr; 01864 return AST_SUCCESS; 01865 }
Attempt transfer of SIP call This fix for attended transfers on a local PBX.
Definition at line 13729 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.
13730 { 13731 int res = 0; 13732 struct ast_channel *peera = NULL, 13733 *peerb = NULL, 13734 *peerc = NULL, 13735 *peerd = NULL; 13736 13737 13738 /* We will try to connect the transferee with the target and hangup 13739 all channels to the transferer */ 13740 if (option_debug > 3) { 13741 ast_log(LOG_DEBUG, "Sip transfer:--------------------\n"); 13742 if (transferer->chan1) 13743 ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 13744 else 13745 ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n"); 13746 if (target->chan1) 13747 ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 13748 else 13749 ast_log(LOG_DEBUG, "-- No target first channel ---\n"); 13750 if (transferer->chan2) 13751 ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 13752 else 13753 ast_log(LOG_DEBUG, "-- No bridged call to transferee\n"); 13754 if (target->chan2) 13755 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)"); 13756 else 13757 ast_log(LOG_DEBUG, "-- No target second channel ---\n"); 13758 ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n"); 13759 } 13760 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 13761 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 13762 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 13763 peerc = transferer->chan2; /* Asterisk to Transferee */ 13764 peerd = target->chan2; /* Asterisk to Target */ 13765 if (option_debug > 2) 13766 ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n"); 13767 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 13768 peera = target->chan1; /* Transferer to PBX -> target channel */ 13769 peerb = transferer->chan1; /* Transferer to IVR*/ 13770 peerc = target->chan2; /* Asterisk to Target */ 13771 peerd = transferer->chan2; /* Nothing */ 13772 if (option_debug > 2) 13773 ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n"); 13774 } 13775 13776 if (peera && peerb && peerc && (peerb != peerc)) { 13777 ast_quiet_chan(peera); /* Stop generators */ 13778 ast_quiet_chan(peerb); 13779 ast_quiet_chan(peerc); 13780 if (peerd) 13781 ast_quiet_chan(peerd); 13782 13783 if (option_debug > 3) 13784 ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 13785 if (ast_channel_masquerade(peerb, peerc)) { 13786 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 13787 res = -1; 13788 } else 13789 ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n"); 13790 return res; 13791 } else { 13792 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 13793 if (transferer->chan1) 13794 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 13795 if (target->chan1) 13796 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 13797 return -2; 13798 } 13799 return 0; 13800 }
static int auto_congest | ( | const void * | nothing | ) | [static] |
Scheduled congestion on a call.
Definition at line 2995 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.
02996 { 02997 struct sip_pvt *p = (struct sip_pvt *)nothing; 02998 02999 ast_mutex_lock(&p->lock); 03000 p->initid = -1; 03001 if (p->owner) { 03002 /* XXX fails on possible deadlock */ 03003 if (!ast_channel_trylock(p->owner)) { 03004 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 03005 append_history(p, "Cong", "Auto-congesting (timer)"); 03006 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 03007 ast_channel_unlock(p->owner); 03008 } 03009 } 03010 ast_mutex_unlock(&p->lock); 03011 return 0; 03012 }
static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 4536 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().
04537 { 04538 char buf[33]; 04539 04540 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip)); 04541 04542 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04543 04544 }
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 4547 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().
04548 { 04549 char buf[33]; 04550 04551 const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip)); 04552 04553 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04554 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 7101 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().
07102 { 07103 /* Construct Contact: header */ 07104 if (ourport != STANDARD_SIP_PORT) 07105 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); 07106 else 07107 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip)); 07108 }
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 17495 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, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, ast_variable::name, sip_peer::name, ast_variable::next, sip_peer::objflags, option_debug, peerl, sip_peer::pickupgroup, sip_peer::prefs, reg_source_db(), sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sched, sip_peer::secret, set_peer_defaults(), sip_destroy_peer(), SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_SUBSCRIBEMWIONLY, sip_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.
17496 { 17497 struct sip_peer *peer = NULL; 17498 struct ast_ha *oldha = NULL; 17499 int obproxyfound=0; 17500 int found=0; 17501 int firstpass=1; 17502 int format=0; /* Ama flags */ 17503 time_t regseconds = 0; 17504 char *varname = NULL, *varval = NULL; 17505 struct ast_variable *tmpvar = NULL; 17506 struct ast_flags peerflags[2] = {{(0)}}; 17507 struct ast_flags mask[2] = {{(0)}}; 17508 char fullcontact[sizeof(peer->fullcontact)] = ""; 17509 17510 if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 17511 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 17512 /* We also use a case-sensitive comparison (unlike find_peer) so 17513 that case changes made to the peer name will be properly handled 17514 during reload 17515 */ 17516 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 17517 17518 if (peer) { 17519 /* Already in the list, remove it and it will be added back (or FREE'd) */ 17520 found = 1; 17521 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 17522 firstpass = 0; 17523 } else { 17524 if (!(peer = ast_calloc(1, sizeof(*peer)))) 17525 return NULL; 17526 17527 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 17528 rpeerobjs++; 17529 else 17530 speerobjs++; 17531 ASTOBJ_INIT(peer); 17532 } 17533 /* Note that our peer HAS had its reference count incrased */ 17534 if (firstpass) { 17535 peer->lastmsgssent = -1; 17536 oldha = peer->ha; 17537 peer->ha = NULL; 17538 set_peer_defaults(peer); /* Set peer defaults */ 17539 } 17540 if (!found && name) 17541 ast_copy_string(peer->name, name, sizeof(peer->name)); 17542 17543 /* If we have channel variables, remove them (reload) */ 17544 if (peer->chanvars) { 17545 ast_variables_destroy(peer->chanvars); 17546 peer->chanvars = NULL; 17547 /* XXX should unregister ? */ 17548 } 17549 17550 /* If we have realm authentication information, remove them (reload) */ 17551 clear_realm_authentication(peer->auth); 17552 peer->auth = NULL; 17553 17554 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 17555 if (handle_common_options(&peerflags[0], &mask[0], v)) 17556 continue; 17557 if (realtime && !strcasecmp(v->name, "regseconds")) { 17558 ast_get_time_t(v->value, ®seconds, 0, NULL); 17559 } else if (realtime && !strcasecmp(v->name, "lastms")) { 17560 sscanf(v->value, "%d", &peer->lastms); 17561 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 17562 inet_aton(v->value, &(peer->addr.sin_addr)); 17563 } else if (realtime && !strcasecmp(v->name, "name")) 17564 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 17565 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 17566 /* Reconstruct field, because realtime separates our value at the ';' */ 17567 if (!ast_strlen_zero(fullcontact)) { 17568 strncat(fullcontact, ";", sizeof(fullcontact) - strlen(fullcontact) - 1); 17569 strncat(fullcontact, v->value, sizeof(fullcontact) - strlen(fullcontact) - 1); 17570 } else { 17571 ast_copy_string(fullcontact, v->value, sizeof(fullcontact)); 17572 ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT); 17573 } 17574 } else if (!strcasecmp(v->name, "secret")) 17575 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 17576 else if (!strcasecmp(v->name, "md5secret")) 17577 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 17578 else if (!strcasecmp(v->name, "auth")) 17579 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 17580 else if (!strcasecmp(v->name, "callerid")) { 17581 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 17582 } else if (!strcasecmp(v->name, "fullname")) { 17583 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 17584 } else if (!strcasecmp(v->name, "cid_number")) { 17585 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 17586 } else if (!strcasecmp(v->name, "context")) { 17587 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 17588 } else if (!strcasecmp(v->name, "subscribecontext")) { 17589 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 17590 } else if (!strcasecmp(v->name, "fromdomain")) { 17591 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 17592 } else if (!strcasecmp(v->name, "usereqphone")) { 17593 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 17594 } else if (!strcasecmp(v->name, "fromuser")) { 17595 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 17596 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 17597 if (!strcasecmp(v->value, "dynamic")) { 17598 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 17599 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 17600 } else { 17601 /* They'll register with us */ 17602 if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 17603 /* Initialize stuff if this is a new peer, or if it used to be 17604 * non-dynamic before the reload. */ 17605 memset(&peer->addr.sin_addr, 0, 4); 17606 if (peer->addr.sin_port) { 17607 /* If we've already got a port, make it the default rather than absolute */ 17608 peer->defaddr.sin_port = peer->addr.sin_port; 17609 peer->addr.sin_port = 0; 17610 } 17611 } 17612 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 17613 } 17614 } else { 17615 /* Non-dynamic. Make sure we become that way if we're not */ 17616 if (!AST_SCHED_DEL(sched, peer->expire)) { 17617 struct sip_peer *peer_ptr = peer; 17618 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17619 } 17620 ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 17621 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 17622 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 17623 ASTOBJ_UNREF(peer, sip_destroy_peer); 17624 return NULL; 17625 } 17626 } 17627 if (!strcasecmp(v->name, "outboundproxy")) 17628 obproxyfound=1; 17629 else { 17630 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 17631 if (!peer->addr.sin_port) 17632 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 17633 } 17634 if (global_dynamic_exclude_static) { 17635 global_contact_ha = ast_append_ha("deny", (char *)ast_inet_ntoa(peer->addr.sin_addr), global_contact_ha); 17636 } 17637 } 17638 } else if (!strcasecmp(v->name, "defaultip")) { 17639 if (ast_get_ip(&peer->defaddr, v->value)) { 17640 ASTOBJ_UNREF(peer, sip_destroy_peer); 17641 return NULL; 17642 } 17643 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 17644 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 17645 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 17646 peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha); 17647 } else if (!strcasecmp(v->name, "port")) { 17648 if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) 17649 peer->defaddr.sin_port = htons(atoi(v->value)); 17650 else 17651 peer->addr.sin_port = htons(atoi(v->value)); 17652 } else if (!strcasecmp(v->name, "callingpres")) { 17653 peer->callingpres = ast_parse_caller_presentation(v->value); 17654 if (peer->callingpres == -1) 17655 peer->callingpres = atoi(v->value); 17656 } else if (!strcasecmp(v->name, "username")) { 17657 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 17658 } else if (!strcasecmp(v->name, "language")) { 17659 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 17660 } else if (!strcasecmp(v->name, "regexten")) { 17661 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 17662 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 17663 peer->call_limit = atoi(v->value); 17664 if (peer->call_limit < 0) 17665 peer->call_limit = 0; 17666 } else if (!strcasecmp(v->name, "amaflags")) { 17667 format = ast_cdr_amaflags2int(v->value); 17668 if (format < 0) { 17669 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 17670 } else { 17671 peer->amaflags = format; 17672 } 17673 } else if (!strcasecmp(v->name, "accountcode")) { 17674 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 17675 } else if (!strcasecmp(v->name, "mohinterpret") 17676 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17677 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 17678 } else if (!strcasecmp(v->name, "mohsuggest")) { 17679 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 17680 } else if (!strcasecmp(v->name, "mailbox")) { 17681 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 17682 } else if (!strcasecmp(v->name, "hasvoicemail")) { 17683 /* People expect that if 'hasvoicemail' is set, that the mailbox will 17684 * be also set, even if not explicitly specified. */ 17685 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 17686 ast_copy_string(peer->mailbox, name, sizeof(peer->mailbox)); 17687 } 17688 } else if (!strcasecmp(v->name, "subscribemwi")) { 17689 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 17690 } else if (!strcasecmp(v->name, "vmexten")) { 17691 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 17692 } else if (!strcasecmp(v->name, "callgroup")) { 17693 peer->callgroup = ast_get_group(v->value); 17694 } else if (!strcasecmp(v->name, "allowtransfer")) { 17695 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17696 } else if (!strcasecmp(v->name, "pickupgroup")) { 17697 peer->pickupgroup = ast_get_group(v->value); 17698 } else if (!strcasecmp(v->name, "allow")) { 17699 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 17700 } else if (!strcasecmp(v->name, "disallow")) { 17701 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 17702 } else if (!strcasecmp(v->name, "autoframing")) { 17703 peer->autoframing = ast_true(v->value); 17704 } else if (!strcasecmp(v->name, "rtptimeout")) { 17705 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 17706 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17707 peer->rtptimeout = global_rtptimeout; 17708 } 17709 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 17710 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 17711 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17712 peer->rtpholdtimeout = global_rtpholdtimeout; 17713 } 17714 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 17715 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 17716 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 17717 peer->rtpkeepalive = global_rtpkeepalive; 17718 } 17719 } else if (!strcasecmp(v->name, "setvar")) { 17720 /* Set peer channel variable */ 17721 varname = ast_strdupa(v->value); 17722 if ((varval = strchr(varname, '='))) { 17723 *varval++ = '\0'; 17724 if ((tmpvar = ast_variable_new(varname, varval))) { 17725 tmpvar->next = peer->chanvars; 17726 peer->chanvars = tmpvar; 17727 } 17728 } 17729 } else if (!strcasecmp(v->name, "qualify")) { 17730 if (!strcasecmp(v->value, "no")) { 17731 peer->maxms = 0; 17732 } else if (!strcasecmp(v->value, "yes")) { 17733 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 17734 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 17735 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); 17736 peer->maxms = 0; 17737 } 17738 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) { 17739 /* This would otherwise cause a network storm, where the 17740 * qualify response refreshes the peer from the database, 17741 * which in turn causes another qualify to be sent, ad 17742 * infinitum. */ 17743 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); 17744 peer->maxms = 0; 17745 } 17746 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17747 peer->maxcallbitrate = atoi(v->value); 17748 if (peer->maxcallbitrate < 0) 17749 peer->maxcallbitrate = default_maxcallbitrate; 17750 } 17751 } 17752 if (!ast_strlen_zero(fullcontact)) { 17753 ast_copy_string(peer->fullcontact, fullcontact, sizeof(peer->fullcontact)); 17754 /* We have a hostname in the fullcontact, but if we don't have an 17755 * address listed on the entry (or if it's 'dynamic'), then we need to 17756 * parse the entry to obtain the IP address, so a dynamic host can be 17757 * contacted immediately after reload (as opposed to waiting for it to 17758 * register once again). */ 17759 __set_address_from_contact(fullcontact, &peer->addr); 17760 } 17761 17762 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) { 17763 time_t nowtime = time(NULL); 17764 17765 if ((nowtime - regseconds) > 0) { 17766 destroy_association(peer); 17767 memset(&peer->addr, 0, sizeof(peer->addr)); 17768 peer->lastms = -1; 17769 if (option_debug) 17770 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 17771 } 17772 } 17773 17774 /* Startup regular pokes */ 17775 if (realtime && peer->lastms > 0) { 17776 ASTOBJ_REF(peer); 17777 sip_poke_peer(peer); 17778 } 17779 17780 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 17781 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 17782 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 17783 global_allowsubscribe = TRUE; /* No global ban any more */ 17784 if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME)) 17785 reg_source_db(peer); 17786 ASTOBJ_UNMARK(peer); 17787 ast_free_ha(oldha); 17788 return peer; 17789 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 11989 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().
11990 { 11991 char a1[256]; 11992 char a2[256]; 11993 char a1_hash[256]; 11994 char a2_hash[256]; 11995 char resp[256]; 11996 char resp_hash[256]; 11997 char uri[256]; 11998 char opaque[256] = ""; 11999 char cnonce[80]; 12000 const char *username; 12001 const char *secret; 12002 const char *md5secret; 12003 struct sip_auth *auth = NULL; /* Realm authentication */ 12004 12005 if (!ast_strlen_zero(p->domain)) 12006 ast_copy_string(uri, p->domain, sizeof(uri)); 12007 else if (!ast_strlen_zero(p->uri)) 12008 ast_copy_string(uri, p->uri, sizeof(uri)); 12009 else 12010 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr)); 12011 12012 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 12013 12014 /* Check if we have separate auth credentials */ 12015 if(!(auth = find_realm_authentication(p->peerauth, p->realm))) /* Start with peer list */ 12016 auth = find_realm_authentication(authl, p->realm); /* If not, global list */ 12017 12018 if (auth) { 12019 if (sipdebug && option_debug > 1) 12020 ast_log(LOG_DEBUG, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username); 12021 username = auth->username; 12022 secret = auth->secret; 12023 md5secret = auth->md5secret; 12024 if (sipdebug) 12025 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 12026 } else { 12027 /* No authentication, use peer or register= config */ 12028 username = p->authname; 12029 secret = p->peersecret; 12030 md5secret = p->peermd5secret; 12031 } 12032 if (ast_strlen_zero(username)) /* We have no authentication */ 12033 return -1; 12034 12035 /* Calculate SIP digest response */ 12036 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 12037 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 12038 if (!ast_strlen_zero(md5secret)) 12039 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 12040 else 12041 ast_md5_hash(a1_hash,a1); 12042 ast_md5_hash(a2_hash,a2); 12043 12044 p->noncecount++; 12045 if (!ast_strlen_zero(p->qop)) 12046 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 12047 else 12048 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 12049 ast_md5_hash(resp_hash, resp); 12050 12051 /* only include the opaque string if it's set */ 12052 if (!ast_strlen_zero(p->opaque)) { 12053 snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque); 12054 } 12055 12056 /* XXX We hard code our qop to "auth" for now. XXX */ 12057 if (!ast_strlen_zero(p->qop)) 12058 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); 12059 else 12060 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); 12061 12062 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 12063 12064 return 0; 12065 }
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 8567 of file chan_sip.c.
References __get_header(), ast_copy_string(), ast_log(), ast_malloc, ast_strlen_zero(), free_old_route(), get_header(), sip_route::hop, len(), list_route(), LOG_DEBUG, sip_route::next, option_debug, sip_pvt::route, sip_pvt::route_persistant, and sip_debug_test_pvt().
Referenced by handle_request_invite(), and handle_response_invite().
08568 { 08569 struct sip_route *thishop, *head, *tail; 08570 int start = 0; 08571 int len; 08572 const char *rr, *contact, *c; 08573 08574 /* Once a persistant route is set, don't fool with it */ 08575 if (p->route && p->route_persistant) { 08576 if (option_debug) 08577 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 08578 return; 08579 } 08580 08581 if (p->route) { 08582 free_old_route(p->route); 08583 p->route = NULL; 08584 } 08585 08586 /* We only want to create the route set the first time this is called */ 08587 p->route_persistant = 1; 08588 08589 /* Build a tailq, then assign it to p->route when done. 08590 * If backwards, we add entries from the head so they end up 08591 * in reverse order. However, we do need to maintain a correct 08592 * tail pointer because the contact is always at the end. 08593 */ 08594 head = NULL; 08595 tail = head; 08596 /* 1st we pass through all the hops in any Record-Route headers */ 08597 for (;;) { 08598 /* Each Record-Route header */ 08599 rr = __get_header(req, "Record-Route", &start); 08600 if (*rr == '\0') 08601 break; 08602 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 08603 ++rr; 08604 len = strcspn(rr, ">") + 1; 08605 /* Make a struct route */ 08606 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08607 /* ast_calloc is not needed because all fields are initialized in this block */ 08608 ast_copy_string(thishop->hop, rr, len); 08609 if (option_debug > 1) 08610 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 08611 /* Link in */ 08612 if (backwards) { 08613 /* Link in at head so they end up in reverse order */ 08614 thishop->next = head; 08615 head = thishop; 08616 /* If this was the first then it'll be the tail */ 08617 if (!tail) 08618 tail = thishop; 08619 } else { 08620 thishop->next = NULL; 08621 /* Link in at the end */ 08622 if (tail) 08623 tail->next = thishop; 08624 else 08625 head = thishop; 08626 tail = thishop; 08627 } 08628 } 08629 } 08630 } 08631 08632 /* Only append the contact if we are dealing with a strict router */ 08633 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 08634 /* 2nd append the Contact: if there is one */ 08635 /* Can be multiple Contact headers, comma separated values - we just take the first */ 08636 contact = get_header(req, "Contact"); 08637 if (!ast_strlen_zero(contact)) { 08638 if (option_debug > 1) 08639 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 08640 /* Look for <: delimited address */ 08641 c = strchr(contact, '<'); 08642 if (c) { 08643 /* Take to > */ 08644 ++c; 08645 len = strcspn(c, ">") + 1; 08646 } else { 08647 /* No <> - just take the lot */ 08648 c = contact; 08649 len = strlen(contact) + 1; 08650 } 08651 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08652 /* ast_calloc is not needed because all fields are initialized in this block */ 08653 ast_copy_string(thishop->hop, c, len); 08654 thishop->next = NULL; 08655 /* Goes at the end */ 08656 if (tail) 08657 tail->next = thishop; 08658 else 08659 head = thishop; 08660 } 08661 } 08662 } 08663 08664 /* Store as new route */ 08665 p->route = head; 08666 08667 /* For debugging dump what we ended up with */ 08668 if (sip_debug_test_pvt(p)) 08669 list_route(p->route); 08670 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 7111 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().
07112 { 07113 int send_pres_tags = TRUE; 07114 const char *privacy=NULL; 07115 const char *screen=NULL; 07116 char buf[256]; 07117 const char *clid = default_callerid; 07118 const char *clin = NULL; 07119 const char *fromdomain; 07120 07121 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 07122 return; 07123 07124 if (p->owner && p->owner->cid.cid_num) 07125 clid = p->owner->cid.cid_num; 07126 if (p->owner && p->owner->cid.cid_name) 07127 clin = p->owner->cid.cid_name; 07128 if (ast_strlen_zero(clin)) 07129 clin = clid; 07130 07131 switch (p->callingpres) { 07132 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 07133 privacy = "off"; 07134 screen = "no"; 07135 break; 07136 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 07137 privacy = "off"; 07138 screen = "yes"; 07139 break; 07140 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 07141 privacy = "off"; 07142 screen = "no"; 07143 break; 07144 case AST_PRES_ALLOWED_NETWORK_NUMBER: 07145 privacy = "off"; 07146 screen = "yes"; 07147 break; 07148 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 07149 privacy = "full"; 07150 screen = "no"; 07151 break; 07152 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 07153 privacy = "full"; 07154 screen = "yes"; 07155 break; 07156 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 07157 privacy = "full"; 07158 screen = "no"; 07159 break; 07160 case AST_PRES_PROHIB_NETWORK_NUMBER: 07161 privacy = "full"; 07162 screen = "yes"; 07163 break; 07164 case AST_PRES_NUMBER_NOT_AVAILABLE: 07165 send_pres_tags = FALSE; 07166 break; 07167 default: 07168 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 07169 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 07170 privacy = "full"; 07171 else 07172 privacy = "off"; 07173 screen = "no"; 07174 break; 07175 } 07176 07177 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 07178 07179 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 07180 if (send_pres_tags) 07181 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 07182 ast_string_field_set(p, rpid, buf); 07183 07184 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 07185 S_OR(p->fromuser, clid), 07186 fromdomain, p->tag); 07187 }
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 17315 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.
17316 { 17317 struct sip_user *user; 17318 int format; 17319 struct ast_ha *oldha = NULL; 17320 char *varname = NULL, *varval = NULL; 17321 struct ast_variable *tmpvar = NULL; 17322 struct ast_flags userflags[2] = {{(0)}}; 17323 struct ast_flags mask[2] = {{(0)}}; 17324 17325 17326 if (!(user = ast_calloc(1, sizeof(*user)))) 17327 return NULL; 17328 17329 suserobjs++; 17330 ASTOBJ_INIT(user); 17331 ast_copy_string(user->name, name, sizeof(user->name)); 17332 oldha = user->ha; 17333 user->ha = NULL; 17334 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 17335 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 17336 user->capability = global_capability; 17337 user->allowtransfer = global_allowtransfer; 17338 user->maxcallbitrate = default_maxcallbitrate; 17339 user->autoframing = global_autoframing; 17340 user->prefs = default_prefs; 17341 /* set default context */ 17342 strcpy(user->context, default_context); 17343 strcpy(user->language, default_language); 17344 strcpy(user->mohinterpret, default_mohinterpret); 17345 strcpy(user->mohsuggest, default_mohsuggest); 17346 /* First we walk through the v parameters list and then the alt parameters list */ 17347 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 17348 if (handle_common_options(&userflags[0], &mask[0], v)) 17349 continue; 17350 17351 if (!strcasecmp(v->name, "context")) { 17352 ast_copy_string(user->context, v->value, sizeof(user->context)); 17353 } else if (!strcasecmp(v->name, "subscribecontext")) { 17354 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 17355 } else if (!strcasecmp(v->name, "setvar")) { 17356 varname = ast_strdupa(v->value); 17357 if ((varval = strchr(varname,'='))) { 17358 *varval++ = '\0'; 17359 if ((tmpvar = ast_variable_new(varname, varval))) { 17360 tmpvar->next = user->chanvars; 17361 user->chanvars = tmpvar; 17362 } 17363 } 17364 } else if (!strcasecmp(v->name, "permit") || 17365 !strcasecmp(v->name, "deny")) { 17366 user->ha = ast_append_ha(v->name, v->value, user->ha); 17367 } else if (!strcasecmp(v->name, "allowtransfer")) { 17368 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17369 } else if (!strcasecmp(v->name, "secret")) { 17370 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 17371 } else if (!strcasecmp(v->name, "md5secret")) { 17372 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 17373 } else if (!strcasecmp(v->name, "callerid")) { 17374 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 17375 } else if (!strcasecmp(v->name, "fullname")) { 17376 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 17377 } else if (!strcasecmp(v->name, "cid_number")) { 17378 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 17379 } else if (!strcasecmp(v->name, "callgroup")) { 17380 user->callgroup = ast_get_group(v->value); 17381 } else if (!strcasecmp(v->name, "pickupgroup")) { 17382 user->pickupgroup = ast_get_group(v->value); 17383 } else if (!strcasecmp(v->name, "language")) { 17384 ast_copy_string(user->language, v->value, sizeof(user->language)); 17385 } else if (!strcasecmp(v->name, "mohinterpret") 17386 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17387 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 17388 } else if (!strcasecmp(v->name, "mohsuggest")) { 17389 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 17390 } else if (!strcasecmp(v->name, "accountcode")) { 17391 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 17392 } else if (!strcasecmp(v->name, "call-limit")) { 17393 user->call_limit = atoi(v->value); 17394 if (user->call_limit < 0) 17395 user->call_limit = 0; 17396 } else if (!strcasecmp(v->name, "amaflags")) { 17397 format = ast_cdr_amaflags2int(v->value); 17398 if (format < 0) { 17399 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 17400 } else { 17401 user->amaflags = format; 17402 } 17403 } else if (!strcasecmp(v->name, "allow")) { 17404 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 17405 } else if (!strcasecmp(v->name, "disallow")) { 17406 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 17407 } else if (!strcasecmp(v->name, "autoframing")) { 17408 user->autoframing = ast_true(v->value); 17409 } else if (!strcasecmp(v->name, "callingpres")) { 17410 user->callingpres = ast_parse_caller_presentation(v->value); 17411 if (user->callingpres == -1) 17412 user->callingpres = atoi(v->value); 17413 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17414 user->maxcallbitrate = atoi(v->value); 17415 if (user->maxcallbitrate < 0) 17416 user->maxcallbitrate = default_maxcallbitrate; 17417 } 17418 /* We can't just report unknown options here because this may be a 17419 * type=friend entry. All user options are valid for a peer, but not 17420 * the other way around. */ 17421 } 17422 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 17423 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 17424 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 17425 global_allowsubscribe = TRUE; /* No global ban any more */ 17426 ast_free_ha(oldha); 17427 return user; 17428 }
static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 1819 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().
01820 { 01821 /* Work around buggy UNIDEN UIP200 firmware */ 01822 const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : ""; 01823 01824 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01825 snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s", 01826 ast_inet_ntoa(p->ourip), ourport, (int) p->branch, rport); 01827 }
static int cb_extensionstate | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 8875 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().
08876 { 08877 struct sip_pvt *p = data; 08878 08879 ast_mutex_lock(&p->lock); 08880 08881 switch(state) { 08882 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 08883 case AST_EXTENSION_REMOVED: /* Extension is gone */ 08884 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 08885 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08886 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 08887 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); 08888 p->stateid = -1; 08889 p->subscribed = NONE; 08890 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 08891 break; 08892 default: /* Tell user */ 08893 p->laststate = state; 08894 break; 08895 } 08896 if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */ 08897 if (!p->pendinginvite) { 08898 transmit_state_notify(p, state, 1, FALSE); 08899 } else { 08900 /* We already have a NOTIFY sent that is not answered. Queue the state up. 08901 if many state changes happen meanwhile, we will only send a notification of the last one */ 08902 ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 08903 } 08904 } 08905 if (option_verbose > 1) 08906 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, 08907 ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : ""); 08908 08909 08910 ast_mutex_unlock(&p->lock); 08911 08912 return 0; 08913 }
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 5121 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().
05122 { 05123 if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 05124 sip_peer_hold(dialog, holdstate); 05125 if (global_callevents) 05126 manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold", 05127 "Channel: %s\r\n" 05128 "Uniqueid: %s\r\n", 05129 dialog->owner->name, 05130 dialog->owner->uniqueid); 05131 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data); 05132 if (!holdstate) { /* Put off remote hold */ 05133 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 05134 return; 05135 } 05136 /* No address for RTP, we're on hold */ 05137 05138 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 05139 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 05140 else if (sendonly == 2) /* Inactive stream */ 05141 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 05142 else 05143 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 05144 return; 05145 }
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 8680 of file chan_sip.c.
References append_history, ast_copy_string(), ast_dynamic_str_thread_get(), ast_dynamic_str_thread_set(), AST_DYNSTR_BUILD_FAILED, ast_log(), ast_md5_hash(), ast_random(), ast_skip_blanks(), ast_string_field_build, ast_strlen_zero(), ast_test_flag, AUTH_CHALLENGE_SENT, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, AUTH_USERNAME_MISMATCH, check_auth_buf, CHECK_AUTH_BUF_INITLEN, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), keys, LOG_NOTICE, sip_pvt::randdata, s, S_OR, sip_methods, SIP_PKT_IGNORE, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, ast_dynamic_str::str, text, transmit_response_with_auth(), and TRUE.
Referenced by check_user_full(), and register_verify().
08683 { 08684 const char *response = "407 Proxy Authentication Required"; 08685 const char *reqheader = "Proxy-Authorization"; 08686 const char *respheader = "Proxy-Authenticate"; 08687 const char *authtoken; 08688 char a1_hash[256]; 08689 char resp_hash[256]=""; 08690 char *c; 08691 int wrongnonce = FALSE; 08692 int good_response; 08693 const char *usednonce = p->randdata; 08694 struct ast_dynamic_str *buf; 08695 int res; 08696 08697 /* table of recognised keywords, and their value in the digest */ 08698 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 08699 struct x { 08700 const char *key; 08701 const char *s; 08702 } *i, keys[] = { 08703 [K_RESP] = { "response=", "" }, 08704 [K_URI] = { "uri=", "" }, 08705 [K_USER] = { "username=", "" }, 08706 [K_NONCE] = { "nonce=", "" }, 08707 [K_LAST] = { NULL, NULL} 08708 }; 08709 08710 /* Always OK if no secret */ 08711 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 08712 return AUTH_SUCCESSFUL; 08713 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 08714 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 08715 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 08716 different circumstances! What a surprise. */ 08717 response = "401 Unauthorized"; 08718 reqheader = "Authorization"; 08719 respheader = "WWW-Authenticate"; 08720 } 08721 authtoken = get_header(req, reqheader); 08722 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 08723 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 08724 information */ 08725 if (!reliable) { 08726 /* Resend message if this was NOT a reliable delivery. Otherwise the 08727 retransmission should get it */ 08728 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08729 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 08730 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08731 } 08732 return AUTH_CHALLENGE_SENT; 08733 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 08734 /* We have no auth, so issue challenge and request authentication */ 08735 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08736 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08737 /* Schedule auto destroy in 32 seconds */ 08738 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08739 return AUTH_CHALLENGE_SENT; 08740 } 08741 08742 /* --- We have auth, so check it */ 08743 08744 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 08745 an example in the spec of just what it is you're doing a hash on. */ 08746 08747 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) 08748 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08749 08750 /* Make a copy of the response and parse it */ 08751 res = ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken); 08752 08753 if (res == AST_DYNSTR_BUILD_FAILED) 08754 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08755 08756 c = buf->str; 08757 08758 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 08759 for (i = keys; i->key != NULL; i++) { 08760 const char *separator = ","; /* default */ 08761 08762 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 08763 continue; 08764 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08765 c += strlen(i->key); 08766 if (*c == '"') { /* in quotes. Skip first and look for last */ 08767 c++; 08768 separator = "\""; 08769 } 08770 i->s = c; 08771 strsep(&c, separator); 08772 break; 08773 } 08774 if (i->key == NULL) /* not found, jump after space or comma */ 08775 strsep(&c, " ,"); 08776 } 08777 08778 /* Verify that digest username matches the username we auth as */ 08779 if (strcmp(username, keys[K_USER].s)) { 08780 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 08781 username, keys[K_USER].s); 08782 /* Oops, we're trying something here */ 08783 return AUTH_USERNAME_MISMATCH; 08784 } 08785 08786 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 08787 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */ 08788 wrongnonce = TRUE; 08789 usednonce = keys[K_NONCE].s; 08790 } 08791 08792 if (!ast_strlen_zero(md5secret)) 08793 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 08794 else { 08795 char a1[256]; 08796 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 08797 ast_md5_hash(a1_hash, a1); 08798 } 08799 08800 /* compute the expected response to compare with what we received */ 08801 { 08802 char a2[256]; 08803 char a2_hash[256]; 08804 char resp[256]; 08805 08806 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 08807 S_OR(keys[K_URI].s, uri)); 08808 ast_md5_hash(a2_hash, a2); 08809 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 08810 ast_md5_hash(resp_hash, resp); 08811 } 08812 08813 good_response = keys[K_RESP].s && 08814 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 08815 if (wrongnonce) { 08816 if (good_response) { 08817 if (sipdebug) 08818 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To")); 08819 /* We got working auth token, based on stale nonce . */ 08820 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08821 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 08822 } else { 08823 /* Everything was wrong, so give the device one more try with a new challenge */ 08824 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 08825 if (sipdebug) 08826 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 08827 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08828 } else { 08829 if (sipdebug) 08830 ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To")); 08831 } 08832 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 08833 } 08834 08835 /* Schedule auto destroy in 32 seconds */ 08836 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08837 return AUTH_CHALLENGE_SENT; 08838 } 08839 if (good_response) { 08840 append_history(p, "AuthOK", "Auth challenge succesful for %s", username); 08841 return AUTH_SUCCESSFUL; 08842 } 08843 08844 /* Ok, we have a bad username/secret pair */ 08845 /* Tell the UAS not to re-send this authentication data, because 08846 it will continue to fail 08847 */ 08848 08849 return AUTH_SECRET_FAILED; 08850 }
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 12464 of file chan_sip.c.
References ast_clear_flag, ast_log(), ast_test_flag, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, INV_CALLING, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, LOG_DEBUG, option_debug, sip_pvt::pendinginvite, SIP_BYE, SIP_CANCEL, SIP_NEEDREINVITE, SIP_PENDINGBYE, sip_scheddestroy(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), TRUE, sip_pvt::waitid, and XMIT_RELIABLE.
Referenced by handle_request(), and handle_response_invite().
12465 { 12466 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 12467 /* if we can't BYE, then this is really a pending CANCEL */ 12468 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) 12469 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 12470 /* Actually don't destroy us yet, wait for the 487 on our original 12471 INVITE, but do set an autodestruct just in case we never get it. */ 12472 else { 12473 /* We have a pending outbound invite, don't send someting 12474 new in-transaction */ 12475 if (p->pendinginvite) 12476 return; 12477 12478 /* Perhaps there is an SD change INVITE outstanding */ 12479 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 12480 } 12481 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 12482 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12483 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 12484 /* if we can't REINVITE, hold it for later */ 12485 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 12486 if (option_debug) 12487 ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 12488 } else { 12489 if (option_debug) 12490 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 12491 /* Didn't get to reinvite yet, so do it now */ 12492 transmit_reinvite_with_sdp(p); 12493 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 12494 } 12495 } 12496 }
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 17194 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().
17195 { 17196 struct domain *d; 17197 int result = 0; 17198 17199 AST_LIST_LOCK(&domain_list); 17200 AST_LIST_TRAVERSE(&domain_list, d, list) { 17201 if (strcasecmp(d->domain, domain)) 17202 continue; 17203 17204 if (len && !ast_strlen_zero(d->context)) 17205 ast_copy_string(context, d->context, len); 17206 17207 result = 1; 17208 break; 17209 } 17210 AST_LIST_UNLOCK(&domain_list); 17211 17212 return result; 17213 }
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 10084 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
10085 { 10086 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 10087 }
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 9760 of file chan_sip.c.
References sip_peer::accountcode, sip_user::accountcode, accountcode, sip_user::allowtransfer, sip_peer::amaflags, sip_user::amaflags, ast_apply_ha(), ast_copy_flags, ast_copy_string(), AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_is_shrinkable_phonenumber(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_variable_new(), ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, AUTH_FAKE_AUTH, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, sip_peer::autoframing, sip_user::autoframing, build_contact(), sip_peer::call_limit, sip_user::call_limit, sip_peer::callgroup, sip_user::callgroup, sip_peer::callingpres, sip_user::callingpres, sip_peer::capability, sip_user::capability, sip_peer::chanvars, sip_user::chanvars, check_auth(), sip_peer::cid_name, sip_user::cid_name, cid_name, sip_peer::cid_num, sip_user::cid_num, cid_num, sip_peer::context, context, sip_user::context, debug, do_setnat(), exten, find_peer(), find_user(), sip_peer::flags, sip_user::flags, sip_peer::fullcontact, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), sip_user::ha, sip_peer::language, sip_user::language, language, sip_peer::lastms, LOG_NOTICE, sip_peer::maxcallbitrate, sip_user::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_user::md5secret, sip_peer::mohinterpret, sip_user::mohinterpret, mohinterpret, sip_peer::mohsuggest, sip_user::mohsuggest, mohsuggest, sip_peer::name, sip_user::name, ast_variable::next, sip_peer::pickupgroup, sip_user::pickupgroup, sip_peer::prefs, sip_user::prefs, sip_peer::secret, sip_user::secret, SIP_CALL_LIMIT, sip_cancel_destroy(), sip_debug_test_addr(), sip_destroy_peer(), sip_destroy_user(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_INSECURE_INVITE, SIP_INVITE, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_VIDEOSUPPORT, SIP_PKT_IGNORE, SIP_SUBSCRIBE, SIP_TRUSTRPID, sip_peer::sipoptions, sip_user::sipoptions, sip_peer::subscribecontext, sip_user::subscribecontext, t, sip_peer::username, and username.
Referenced by check_user(), and handle_request_subscribe().
09763 { 09764 struct sip_user *user = NULL; 09765 struct sip_peer *peer; 09766 char from[256], *c; 09767 char *of; 09768 char rpid_num[50]; 09769 const char *rpid; 09770 enum check_auth_result res = AUTH_SUCCESSFUL; 09771 char *t; 09772 char calleridname[50]; 09773 int debug=sip_debug_test_addr(sin); 09774 struct ast_variable *tmpvar = NULL, *v = NULL; 09775 char *uri2 = ast_strdupa(uri); 09776 09777 /* Terminate URI */ 09778 t = uri2; 09779 while (*t && *t > 32 && *t != ';') 09780 t++; 09781 *t = '\0'; 09782 ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */ 09783 if (pedanticsipchecking) 09784 ast_uri_decode(from); 09785 /* XXX here tries to map the username for invite things */ 09786 memset(calleridname, 0, sizeof(calleridname)); 09787 get_calleridname(from, calleridname, sizeof(calleridname)); 09788 if (calleridname[0]) 09789 ast_string_field_set(p, cid_name, calleridname); 09790 09791 rpid = get_header(req, "Remote-Party-ID"); 09792 memset(rpid_num, 0, sizeof(rpid_num)); 09793 if (!ast_strlen_zero(rpid)) 09794 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 09795 09796 of = get_in_brackets(from); 09797 if (ast_strlen_zero(p->exten)) { 09798 t = uri2; 09799 if (!strncasecmp(t, "sip:", 4)) 09800 t+= 4; 09801 ast_string_field_set(p, exten, t); 09802 t = strchr(p->exten, '@'); 09803 if (t) 09804 *t = '\0'; 09805 if (ast_strlen_zero(p->our_contact)) 09806 build_contact(p); 09807 } 09808 /* save the URI part of the From header */ 09809 ast_string_field_set(p, from, of); 09810 if (strncasecmp(of, "sip:", 4)) { 09811 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 09812 } else 09813 of += 4; 09814 /* Get just the username part */ 09815 if ((c = strchr(of, '@'))) { 09816 char *tmp; 09817 *c = '\0'; 09818 if ((c = strchr(of, ':'))) 09819 *c = '\0'; 09820 tmp = ast_strdupa(of); 09821 /* We need to be able to handle auth-headers looking like 09822 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 09823 */ 09824 tmp = strsep(&tmp, ";"); 09825 if (ast_is_shrinkable_phonenumber(tmp)) 09826 ast_shrink_phone_number(tmp); 09827 ast_string_field_set(p, cid_num, tmp); 09828 } 09829 09830 if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */ 09831 user = find_user(of, 1); 09832 09833 /* Find user based on user name in the from header */ 09834 if (user && ast_apply_ha(user->ha, sin)) { 09835 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09836 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09837 if (sipmethod == SIP_INVITE) { 09838 /* copy channel vars */ 09839 for (v = user->chanvars ; v ; v = v->next) { 09840 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09841 tmpvar->next = p->chanvars; 09842 p->chanvars = tmpvar; 09843 } 09844 } 09845 } 09846 p->prefs = user->prefs; 09847 /* Set Frame packetization */ 09848 if (p->rtp) { 09849 ast_rtp_codec_setpref(p->rtp, &p->prefs); 09850 p->autoframing = user->autoframing; 09851 } 09852 /* replace callerid if rpid found, and not restricted */ 09853 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09854 char *tmp; 09855 if (*calleridname) 09856 ast_string_field_set(p, cid_name, calleridname); 09857 tmp = ast_strdupa(rpid_num); 09858 if (ast_is_shrinkable_phonenumber(tmp)) 09859 ast_shrink_phone_number(tmp); 09860 ast_string_field_set(p, cid_num, tmp); 09861 } 09862 09863 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 09864 09865 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09866 if (sip_cancel_destroy(p)) 09867 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09868 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09869 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09870 /* Copy SIP extensions profile from INVITE */ 09871 if (p->sipoptions) 09872 user->sipoptions = p->sipoptions; 09873 09874 /* If we have a call limit, set flag */ 09875 if (user->call_limit) 09876 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09877 if (!ast_strlen_zero(user->context)) 09878 ast_string_field_set(p, context, user->context); 09879 if (!ast_strlen_zero(user->cid_num)) { 09880 char *tmp = ast_strdupa(user->cid_num); 09881 if (ast_is_shrinkable_phonenumber(tmp)) 09882 ast_shrink_phone_number(tmp); 09883 ast_string_field_set(p, cid_num, tmp); 09884 } 09885 if (!ast_strlen_zero(user->cid_name)) 09886 ast_string_field_set(p, cid_name, user->cid_name); 09887 ast_string_field_set(p, username, user->name); 09888 ast_string_field_set(p, peername, user->name); 09889 ast_string_field_set(p, peersecret, user->secret); 09890 ast_string_field_set(p, peermd5secret, user->md5secret); 09891 ast_string_field_set(p, subscribecontext, user->subscribecontext); 09892 ast_string_field_set(p, accountcode, user->accountcode); 09893 ast_string_field_set(p, language, user->language); 09894 ast_string_field_set(p, mohsuggest, user->mohsuggest); 09895 ast_string_field_set(p, mohinterpret, user->mohinterpret); 09896 p->allowtransfer = user->allowtransfer; 09897 p->amaflags = user->amaflags; 09898 p->callgroup = user->callgroup; 09899 p->pickupgroup = user->pickupgroup; 09900 if (user->callingpres) /* User callingpres setting will override RPID header */ 09901 p->callingpres = user->callingpres; 09902 09903 /* Set default codec settings for this call */ 09904 p->capability = user->capability; /* User codec choice */ 09905 p->jointcapability = user->capability; /* Our codecs */ 09906 if (p->peercapability) /* AND with peer's codecs */ 09907 p->jointcapability &= p->peercapability; 09908 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09909 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09910 p->noncodeccapability |= AST_RTP_DTMF; 09911 else 09912 p->noncodeccapability &= ~AST_RTP_DTMF; 09913 p->jointnoncodeccapability = p->noncodeccapability; 09914 if (p->t38.peercapability) 09915 p->t38.jointcapability &= p->t38.peercapability; 09916 p->maxcallbitrate = user->maxcallbitrate; 09917 /* If we do not support video, remove video from call structure */ 09918 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09919 ast_rtp_destroy(p->vrtp); 09920 p->vrtp = NULL; 09921 } 09922 } 09923 if (user && debug) 09924 ast_verbose("Found user '%s'\n", user->name); 09925 } else { 09926 if (user) { 09927 if (!authpeer && debug) 09928 ast_verbose("Found user '%s', but fails host access\n", user->name); 09929 ASTOBJ_UNREF(user,sip_destroy_user); 09930 } 09931 user = NULL; 09932 } 09933 09934 if (!user) { 09935 /* If we didn't find a user match, check for peers */ 09936 if (sipmethod == SIP_SUBSCRIBE) 09937 /* For subscribes, match on peer name only */ 09938 peer = find_peer(of, NULL, 1, 0); 09939 else 09940 /* Look for peer based on the IP address we received data from */ 09941 /* If peer is registered from this IP address or have this as a default 09942 IP address, this call is from the peer 09943 */ 09944 peer = find_peer(NULL, &p->recv, 1, 0); 09945 09946 if (peer) { 09947 /* Set Frame packetization */ 09948 if (p->rtp) { 09949 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09950 p->autoframing = peer->autoframing; 09951 } 09952 if (debug) 09953 ast_verbose("Found peer '%s'\n", peer->name); 09954 09955 /* Take the peer */ 09956 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09957 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09958 09959 /* Copy SIP extensions profile to peer */ 09960 if (p->sipoptions) 09961 peer->sipoptions = p->sipoptions; 09962 09963 /* replace callerid if rpid found, and not restricted */ 09964 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09965 char *tmp = ast_strdupa(rpid_num); 09966 if (*calleridname) 09967 ast_string_field_set(p, cid_name, calleridname); 09968 if (ast_is_shrinkable_phonenumber(tmp)) 09969 ast_shrink_phone_number(tmp); 09970 ast_string_field_set(p, cid_num, tmp); 09971 } 09972 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 09973 09974 ast_string_field_set(p, peersecret, peer->secret); 09975 ast_string_field_set(p, peermd5secret, peer->md5secret); 09976 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 09977 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 09978 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 09979 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 09980 p->callingpres = peer->callingpres; 09981 if (peer->maxms && peer->lastms) 09982 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 09983 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 09984 /* Pretend there is no required authentication */ 09985 ast_string_field_free(p, peersecret); 09986 ast_string_field_free(p, peermd5secret); 09987 } 09988 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09989 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09990 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09991 /* If we have a call limit, set flag */ 09992 if (peer->call_limit) 09993 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09994 ast_string_field_set(p, peername, peer->name); 09995 ast_string_field_set(p, authname, peer->name); 09996 09997 if (sipmethod == SIP_INVITE) { 09998 /* copy channel vars */ 09999 for (v = peer->chanvars ; v ; v = v->next) { 10000 if ((tmpvar = ast_variable_new(v->name, v->value))) { 10001 tmpvar->next = p->chanvars; 10002 p->chanvars = tmpvar; 10003 } 10004 } 10005 } 10006 if (authpeer) { 10007 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 10008 } 10009 10010 if (!ast_strlen_zero(peer->username)) { 10011 ast_string_field_set(p, username, peer->username); 10012 /* Use the default username for authentication on outbound calls */ 10013 /* XXX this takes the name from the caller... can we override ? */ 10014 ast_string_field_set(p, authname, peer->username); 10015 } 10016 if (!ast_strlen_zero(peer->cid_num)) { 10017 char *tmp = ast_strdupa(peer->cid_num); 10018 if (ast_is_shrinkable_phonenumber(tmp)) 10019 ast_shrink_phone_number(tmp); 10020 ast_string_field_set(p, cid_num, tmp); 10021 } 10022 if (!ast_strlen_zero(peer->cid_name)) 10023 ast_string_field_set(p, cid_name, peer->cid_name); 10024 ast_string_field_set(p, fullcontact, peer->fullcontact); 10025 if (!ast_strlen_zero(peer->context)) 10026 ast_string_field_set(p, context, peer->context); 10027 ast_string_field_set(p, peersecret, peer->secret); 10028 ast_string_field_set(p, peermd5secret, peer->md5secret); 10029 ast_string_field_set(p, language, peer->language); 10030 ast_string_field_set(p, accountcode, peer->accountcode); 10031 p->amaflags = peer->amaflags; 10032 p->callgroup = peer->callgroup; 10033 p->pickupgroup = peer->pickupgroup; 10034 p->capability = peer->capability; 10035 p->prefs = peer->prefs; 10036 p->jointcapability = peer->capability; 10037 if (p->peercapability) 10038 p->jointcapability &= p->peercapability; 10039 p->maxcallbitrate = peer->maxcallbitrate; 10040 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 10041 ast_rtp_destroy(p->vrtp); 10042 p->vrtp = NULL; 10043 } 10044 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 10045 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 10046 p->noncodeccapability |= AST_RTP_DTMF; 10047 else 10048 p->noncodeccapability &= ~AST_RTP_DTMF; 10049 p->jointnoncodeccapability = p->noncodeccapability; 10050 if (p->t38.peercapability) 10051 p->t38.jointcapability &= p->t38.peercapability; 10052 } 10053 ASTOBJ_UNREF(peer, sip_destroy_peer); 10054 } else { 10055 if (debug) 10056 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 10057 10058 /* do we allow guests? */ 10059 if (!global_allowguest) { 10060 if (global_alwaysauthreject) 10061 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 10062 else 10063 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 10064 } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 10065 char *tmp = ast_strdupa(rpid_num); 10066 if (*calleridname) 10067 ast_string_field_set(p, cid_name, calleridname); 10068 if (ast_is_shrinkable_phonenumber(tmp)) 10069 ast_shrink_phone_number(tmp); 10070 ast_string_field_set(p, cid_num, tmp); 10071 } 10072 } 10073 10074 } 10075 10076 if (user) 10077 ASTOBJ_UNREF(user, sip_destroy_user); 10078 return res; 10079 }
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 9628 of file chan_sip.c.
References ahp, ast_copy_string(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_skip_blanks(), ast_verbose(), sip_pvt::flags, get_header(), hp, sip_pvt::sa, sip_debug_test_pvt(), sip_nat_mode(), SIP_NAT_ROUTE, sip_real_dst(), and STANDARD_SIP_PORT.
Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_register(), handle_request_subscribe(), and transmit_response_using_temp().
09629 { 09630 char via[512]; 09631 char *c, *pt; 09632 struct hostent *hp; 09633 struct ast_hostent ahp; 09634 09635 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 09636 09637 /* Work on the leftmost value of the topmost Via header */ 09638 c = strchr(via, ','); 09639 if (c) 09640 *c = '\0'; 09641 09642 /* Check for rport */ 09643 c = strstr(via, ";rport"); 09644 if (c && (c[6] != '=')) /* rport query, not answer */ 09645 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 09646 09647 c = strchr(via, ';'); 09648 if (c) 09649 *c = '\0'; 09650 09651 c = strchr(via, ' '); 09652 if (c) { 09653 *c = '\0'; 09654 c = ast_skip_blanks(c+1); 09655 if (strcasecmp(via, "SIP/2.0/UDP")) { 09656 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 09657 return; 09658 } 09659 pt = strchr(c, ':'); 09660 if (pt) 09661 *pt++ = '\0'; /* remember port pointer */ 09662 hp = ast_gethostbyname(c, &ahp); 09663 if (!hp) { 09664 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 09665 return; 09666 } 09667 memset(&p->sa, 0, sizeof(p->sa)); 09668 p->sa.sin_family = AF_INET; 09669 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 09670 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 09671 09672 if (sip_debug_test_pvt(p)) { 09673 const struct sockaddr_in *dst = sip_real_dst(p); 09674 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 09675 } 09676 } 09677 }
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 10528 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), ast_copy_string(), and AST_MAX_CONTEXT.
10529 { 10530 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 10531 10532 while ((oldcontext = strsep(&old, "&"))) { 10533 stalecontext = '\0'; 10534 ast_copy_string(newlist, new, sizeof(newlist)); 10535 stringp = newlist; 10536 while ((newcontext = strsep(&stringp, "&"))) { 10537 if (strcmp(newcontext, oldcontext) == 0) { 10538 /* This is not the context you're looking for */ 10539 stalecontext = '\0'; 10540 break; 10541 } else if (strcmp(newcontext, oldcontext)) { 10542 stalecontext = oldcontext; 10543 } 10544 10545 } 10546 if (stalecontext) 10547 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 10548 } 10549 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 17287 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().
17288 { 17289 struct sip_auth *a = authlist; 17290 struct sip_auth *b; 17291 17292 while (a) { 17293 b = a; 17294 a = a->next; 17295 free(b); 17296 } 17297 17298 return 1; 17299 }
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 17216 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().
17217 { 17218 struct domain *d; 17219 17220 AST_LIST_LOCK(&domain_list); 17221 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 17222 free(d); 17223 AST_LIST_UNLOCK(&domain_list); 17224 }
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 11342 of file chan_sip.c.
References complete_sip_peer().
11343 { 11344 if (pos == 3) 11345 return complete_sip_peer(word, state, 0); 11346 11347 return NULL; 11348 }
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 11316 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().
11317 { 11318 char *result = NULL; 11319 int wordlen = strlen(word); 11320 int which = 0; 11321 11322 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 11323 /* locking of the object is not required because only the name and flags are being compared */ 11324 if (!strncasecmp(word, iterator->name, wordlen) && 11325 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 11326 ++which > state) 11327 result = ast_strdup(iterator->name); 11328 } while(0) ); 11329 return result; 11330 }
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 11410 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
11411 { 11412 if (pos == 4) 11413 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11414 return NULL; 11415 }
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 11418 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
11419 { 11420 if (pos == 4) 11421 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11422 11423 return NULL; 11424 }
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 11333 of file chan_sip.c.
References complete_sip_peer().
11334 { 11335 if (pos == 3) 11336 return complete_sip_peer(word, state, 0); 11337 11338 return NULL; 11339 }
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 11371 of file chan_sip.c.
References complete_sip_user().
11372 { 11373 if (pos == 3) 11374 return complete_sip_user(word, state, 0); 11375 11376 return NULL; 11377 }
static char * complete_sip_user | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on user name.
Definition at line 11351 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().
11352 { 11353 char *result = NULL; 11354 int wordlen = strlen(word); 11355 int which = 0; 11356 11357 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 11358 /* locking of the object is not required because only the name and flags are being compared */ 11359 if (!strncasecmp(word, iterator->name, wordlen)) { 11360 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 11361 continue; 11362 if (++which > state) { 11363 result = ast_strdup(iterator->name); 11364 } 11365 } 11366 } while(0) ); 11367 return result; 11368 }
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 11293 of file chan_sip.c.
References ast_mutex_lock(), ast_strdup, sip_pvt::callid, iflist, iflock, and sip_pvt::next.
11294 { 11295 int which=0; 11296 struct sip_pvt *cur; 11297 char *c = NULL; 11298 int wordlen = strlen(word); 11299 11300 if (pos != 3) { 11301 return NULL; 11302 } 11303 11304 ast_mutex_lock(&iflock); 11305 for (cur = iflist; cur; cur = cur->next) { 11306 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 11307 c = ast_strdup(cur->callid); 11308 break; 11309 } 11310 } 11311 ast_mutex_unlock(&iflock); 11312 return c; 11313 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 11380 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
11381 { 11382 char *c = NULL; 11383 11384 if (pos == 2) { 11385 int which = 0; 11386 char *cat = NULL; 11387 int wordlen = strlen(word); 11388 11389 /* do completion for notify type */ 11390 11391 if (!notify_types) 11392 return NULL; 11393 11394 while ( (cat = ast_category_browse(notify_types, cat)) ) { 11395 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 11396 c = ast_strdup(cat); 11397 break; 11398 } 11399 } 11400 return c; 11401 } 11402 11403 if (pos > 2) 11404 return complete_sip_peer(word, state, 0); 11405 11406 return NULL; 11407 }
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 5845 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
05846 { 05847 int start = 0; 05848 int copied = 0; 05849 for (;;) { 05850 const char *tmp = __get_header(orig, field, &start); 05851 05852 if (ast_strlen_zero(tmp)) 05853 break; 05854 /* Add what we're responding to */ 05855 add_header(req, field, tmp); 05856 copied++; 05857 } 05858 return copied ? 0 : -1; 05859 }
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 5834 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
05835 { 05836 const char *tmp = get_header(orig, field); 05837 05838 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 05839 return add_header(req, field, tmp); 05840 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 05841 return -1; 05842 }
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 6954 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().
06955 { 06956 long offset; 06957 int x; 06958 offset = ((void *)dst) - ((void *)src); 06959 /* First copy stuff */ 06960 memcpy(dst, src, sizeof(*dst)); 06961 /* Now fix pointer arithmetic */ 06962 for (x=0; x < src->headers; x++) 06963 dst->header[x] += offset; 06964 for (x=0; x < src->lines; x++) 06965 dst->line[x] += offset; 06966 dst->rlPart1 += offset; 06967 dst->rlPart2 += offset; 06968 }
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 5867 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().
05868 { 05869 int copied = 0; 05870 int start = 0; 05871 05872 for (;;) { 05873 char new[512]; 05874 const char *oh = __get_header(orig, field, &start); 05875 05876 if (ast_strlen_zero(oh)) 05877 break; 05878 05879 if (!copied) { /* Only check for empty rport in topmost via header */ 05880 char leftmost[512], *others, *rport; 05881 05882 /* Only work on leftmost value */ 05883 ast_copy_string(leftmost, oh, sizeof(leftmost)); 05884 others = strchr(leftmost, ','); 05885 if (others) 05886 *others++ = '\0'; 05887 05888 /* Find ;rport; (empty request) */ 05889 rport = strstr(leftmost, ";rport"); 05890 if (rport && *(rport+6) == '=') 05891 rport = NULL; /* We already have a parameter to rport */ 05892 05893 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 05894 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 05895 /* We need to add received port - rport */ 05896 char *end; 05897 05898 rport = strstr(leftmost, ";rport"); 05899 05900 if (rport) { 05901 end = strchr(rport + 1, ';'); 05902 if (end) 05903 memmove(rport, end, strlen(end) + 1); 05904 else 05905 *rport = '\0'; 05906 } 05907 05908 /* Add rport to first VIA header if requested */ 05909 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 05910 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05911 ntohs(p->recv.sin_port), 05912 others ? "," : "", others ? others : ""); 05913 } else { 05914 /* We should *always* add a received to the topmost via */ 05915 snprintf(new, sizeof(new), "%s;received=%s%s%s", 05916 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05917 others ? "," : "", others ? others : ""); 05918 } 05919 oh = new; /* the header to copy */ 05920 } /* else add the following via headers untouched */ 05921 add_header(req, field, oh); 05922 copied++; 05923 } 05924 if (!copied) { 05925 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 05926 return -1; 05927 } 05928 return 0; 05929 }
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 2923 of file chan_sip.c.
References ahp, ast_copy_string(), ast_get_srv(), ast_gethostbyname(), ast_log(), ast_string_field_set, ast_strlen_zero(), ASTOBJ_UNREF, create_addr_from_peer(), find_peer(), hp, portno, sip_pvt::recv, sip_pvt::sa, sip_destroy_peer(), STANDARD_SIP_PORT, sip_pvt::timer_t1, and sip_peer::tohost.
02924 { 02925 struct hostent *hp; 02926 struct ast_hostent ahp; 02927 struct sip_peer *p; 02928 char *port; 02929 int portno = 0; 02930 char host[MAXHOSTNAMELEN], *hostn; 02931 char peer[256]; 02932 02933 ast_copy_string(peer, opeer, sizeof(peer)); 02934 port = strchr(peer, ':'); 02935 if (port) 02936 *port++ = '\0'; 02937 dialog->sa.sin_family = AF_INET; 02938 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 02939 p = find_peer(peer, NULL, 1, 0); 02940 02941 if (p) { 02942 int res = create_addr_from_peer(dialog, p); 02943 if (port) { 02944 portno = atoi(port); 02945 dialog->sa.sin_port = dialog->recv.sin_port = htons(portno); 02946 } 02947 ASTOBJ_UNREF(p, sip_destroy_peer); 02948 return res; 02949 } 02950 02951 ast_string_field_set(dialog, tohost, peer); 02952 02953 if (sin) { 02954 memcpy(&dialog->sa.sin_addr, &sin->sin_addr, sizeof(dialog->sa.sin_addr)); 02955 if (!sin->sin_port) { 02956 if (ast_strlen_zero(port) || sscanf(port, "%u", &portno) != 1) { 02957 portno = STANDARD_SIP_PORT; 02958 } 02959 } else { 02960 portno = ntohs(sin->sin_port); 02961 } 02962 } else { 02963 hostn = peer; 02964 /* Section 4.2 of RFC 3263 specifies that if a port number is specified, then 02965 * an A record lookup should be used instead of SRV. 02966 */ 02967 if (!port && srvlookup) { 02968 char service[MAXHOSTNAMELEN]; 02969 int tportno; 02970 int ret; 02971 02972 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 02973 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 02974 if (ret > 0) { 02975 hostn = host; 02976 portno = tportno; 02977 } 02978 } 02979 if (!portno) 02980 portno = port ? atoi(port) : STANDARD_SIP_PORT; 02981 02982 hp = ast_gethostbyname(hostn, &ahp); 02983 if (!hp) { 02984 ast_log(LOG_WARNING, "No such host: %s\n", peer); 02985 return -1; 02986 } 02987 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 02988 } 02989 dialog->sa.sin_port = htons(portno); 02990 dialog->recv = dialog->sa; 02991 return 0; 02992 }
Create address structure from peer reference. return -1 on error, 0 on success.
Definition at line 2814 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().
02815 { 02816 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 02817 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 02818 dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr; 02819 dialog->recv = dialog->sa; 02820 } else 02821 return -1; 02822 02823 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 02824 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 02825 dialog->capability = peer->capability; 02826 if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) { 02827 ast_rtp_destroy(dialog->vrtp); 02828 dialog->vrtp = NULL; 02829 } 02830 dialog->prefs = peer->prefs; 02831 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) { 02832 dialog->t38.capability = global_t38_capability; 02833 if (dialog->udptl) { 02834 if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC ) 02835 dialog->t38.capability |= T38FAX_UDP_EC_FEC; 02836 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY ) 02837 dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 02838 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE ) 02839 dialog->t38.capability |= T38FAX_UDP_EC_NONE; 02840 dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 02841 if (option_debug > 1) 02842 ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability); 02843 } 02844 dialog->t38.jointcapability = dialog->t38.capability; 02845 } else if (dialog->udptl) { 02846 ast_udptl_destroy(dialog->udptl); 02847 dialog->udptl = NULL; 02848 } 02849 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE ); 02850 02851 if (dialog->rtp) { 02852 ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 02853 ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 02854 ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); 02855 ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); 02856 ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); 02857 /* Set Frame packetization */ 02858 ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); 02859 dialog->autoframing = peer->autoframing; 02860 } 02861 if (dialog->vrtp) { 02862 ast_rtp_setdtmf(dialog->vrtp, 0); 02863 ast_rtp_setdtmfcompensate(dialog->vrtp, 0); 02864 ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); 02865 ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); 02866 ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); 02867 } 02868 02869 ast_string_field_set(dialog, peername, peer->name); 02870 ast_string_field_set(dialog, authname, peer->username); 02871 ast_string_field_set(dialog, username, peer->username); 02872 ast_string_field_set(dialog, peersecret, peer->secret); 02873 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 02874 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 02875 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 02876 ast_string_field_set(dialog, tohost, peer->tohost); 02877 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 02878 if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 02879 char *tmpcall; 02880 char *c; 02881 tmpcall = ast_strdupa(dialog->callid); 02882 c = strchr(tmpcall, '@'); 02883 if (c) { 02884 *c = '\0'; 02885 ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain); 02886 } 02887 } 02888 if (ast_strlen_zero(dialog->tohost)) 02889 ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr)); 02890 if (!ast_strlen_zero(peer->fromdomain)) 02891 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 02892 if (!ast_strlen_zero(peer->fromuser)) 02893 ast_string_field_set(dialog, fromuser, peer->fromuser); 02894 if (!ast_strlen_zero(peer->language)) 02895 ast_string_field_set(dialog, language, peer->language); 02896 dialog->maxtime = peer->maxms; 02897 dialog->callgroup = peer->callgroup; 02898 dialog->pickupgroup = peer->pickupgroup; 02899 dialog->peerauth = peer->auth; 02900 dialog->allowtransfer = peer->allowtransfer; 02901 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 02902 /* Minimum is settable or default to 100 ms */ 02903 if (peer->maxms && peer->lastms) 02904 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 02905 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 02906 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 02907 dialog->noncodeccapability |= AST_RTP_DTMF; 02908 else 02909 dialog->noncodeccapability &= ~AST_RTP_DTMF; 02910 dialog->jointnoncodeccapability = dialog->noncodeccapability; 02911 ast_string_field_set(dialog, context, peer->context); 02912 dialog->rtptimeout = peer->rtptimeout; 02913 if (peer->call_limit) 02914 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 02915 dialog->maxcallbitrate = peer->maxcallbitrate; 02916 02917 return 0; 02918 }
static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 8153 of file chan_sip.c.
References ast_db_del(), ast_test_flag, ast_update_realtime(), sip_peer::flags, global_flags, sip_peer::name, SIP_PAGE2_IGNOREREGEXPIRE, and SIP_PAGE2_RT_FROMCONTACT.
Referenced by build_peer(), expire_register(), and parse_register_contact().
08154 { 08155 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 08156 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) { 08157 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL); 08158 ast_update_realtime("sippeers", "name", peer->name, "lastms", "", NULL); 08159 } else 08160 ast_db_del("SIP/Registry", peer->name); 08161 } 08162 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 6998 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().
06999 { 07000 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 07001 07002 if (!*e) 07003 return -1; 07004 req->rlPart1 = e; /* method or protocol */ 07005 e = ast_skip_nonblanks(e); 07006 if (*e) 07007 *e++ = '\0'; 07008 /* Get URI or status code */ 07009 e = ast_skip_blanks(e); 07010 if ( !*e ) 07011 return -1; 07012 ast_trim_blanks(e); 07013 07014 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 07015 if (strlen(e) < 3) /* status code is 3 digits */ 07016 return -1; 07017 req->rlPart2 = e; 07018 } else { /* We have a request */ 07019 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 07020 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 07021 e++; 07022 if (!*e) 07023 return -1; 07024 } 07025 req->rlPart2 = e; /* URI */ 07026 e = ast_skip_nonblanks(e); 07027 if (*e) 07028 *e++ = '\0'; 07029 e = ast_skip_blanks(e); 07030 if (strcasecmp(e, "SIP/2.0") ) { 07031 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 07032 return -1; 07033 } 07034 } 07035 return 1; 07036 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 16493 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.
16494 { 16495 int res; 16496 struct sip_pvt *sip; 16497 struct sip_peer *peer = NULL; 16498 time_t t; 16499 int fastrestart = FALSE; 16500 int lastpeernum = -1; 16501 int curpeernum; 16502 int reloading; 16503 16504 /* Add an I/O event to our SIP UDP socket */ 16505 if (sipsock > -1) 16506 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 16507 16508 /* From here on out, we die whenever asked */ 16509 for(;;) { 16510 /* Check for a reload request */ 16511 ast_mutex_lock(&sip_reload_lock); 16512 reloading = sip_reloading; 16513 sip_reloading = FALSE; 16514 ast_mutex_unlock(&sip_reload_lock); 16515 if (reloading) { 16516 if (option_verbose > 0) 16517 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 16518 sip_do_reload(sip_reloadreason); 16519 16520 /* Change the I/O fd of our UDP socket */ 16521 if (sipsock > -1) { 16522 if (sipsock_read_id) 16523 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 16524 else 16525 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 16526 } else if (sipsock_read_id) { 16527 ast_io_remove(io, sipsock_read_id); 16528 sipsock_read_id = NULL; 16529 } 16530 } 16531 restartsearch: 16532 /* Check for interfaces needing to be killed */ 16533 ast_mutex_lock(&iflock); 16534 t = time(NULL); 16535 /* don't scan the interface list if it hasn't been a reasonable period 16536 of time since the last time we did it (when MWI is being sent, we can 16537 get back to this point every millisecond or less) 16538 */ 16539 for (sip = iflist; !fastrestart && sip; sip = sip->next) { 16540 /*! \note If we can't get a lock on an interface, skip it and come 16541 * back later. Note that there is the possibility of a deadlock with 16542 * sip_hangup otherwise, because sip_hangup is called with the channel 16543 * locked first, and the iface lock is attempted second. 16544 */ 16545 if (ast_mutex_trylock(&sip->lock)) 16546 continue; 16547 16548 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 16549 if (sip->rtp && sip->owner && 16550 (sip->owner->_state == AST_STATE_UP) && 16551 !sip->redirip.sin_addr.s_addr && 16552 sip->t38.state != T38_ENABLED) { 16553 if (sip->lastrtptx && 16554 ast_rtp_get_rtpkeepalive(sip->rtp) && 16555 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) { 16556 /* Need to send an empty RTP packet */ 16557 sip->lastrtptx = time(NULL); 16558 ast_rtp_sendcng(sip->rtp, 0); 16559 } 16560 if (sip->lastrtprx && 16561 (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) && 16562 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) { 16563 /* Might be a timeout now -- see if we're on hold */ 16564 struct sockaddr_in sin; 16565 ast_rtp_get_peer(sip->rtp, &sin); 16566 if (!ast_test_flag(&sip->flags[1], SIP_PAGE2_CALL_ONHOLD) || 16567 (ast_rtp_get_rtpholdtimeout(sip->rtp) && 16568 (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) { 16569 /* Needs a hangup */ 16570 if (ast_rtp_get_rtptimeout(sip->rtp)) { 16571 while (sip->owner && ast_channel_trylock(sip->owner)) { 16572 DEADLOCK_AVOIDANCE(&sip->lock); 16573 } 16574 if (sip->owner) { 16575 ast_log(LOG_NOTICE, 16576 "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 16577 sip->owner->name, 16578 (long) (t - sip->lastrtprx)); 16579 /* Issue a softhangup */ 16580 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 16581 ast_channel_unlock(sip->owner); 16582 /* forget the timeouts for this call, since a hangup 16583 has already been requested and we don't want to 16584 repeatedly request hangups 16585 */ 16586 ast_rtp_set_rtptimeout(sip->rtp, 0); 16587 ast_rtp_set_rtpholdtimeout(sip->rtp, 0); 16588 if (sip->vrtp) { 16589 ast_rtp_set_rtptimeout(sip->vrtp, 0); 16590 ast_rtp_set_rtpholdtimeout(sip->vrtp, 0); 16591 } 16592 } 16593 } 16594 } 16595 } 16596 } 16597 /* If we have sessions that needs to be destroyed, do it now */ 16598 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && 16599 !sip->owner) { 16600 ast_mutex_unlock(&sip->lock); 16601 __sip_destroy(sip, 1); 16602 ast_mutex_unlock(&iflock); 16603 usleep(1); 16604 goto restartsearch; 16605 } 16606 ast_mutex_unlock(&sip->lock); 16607 } 16608 ast_mutex_unlock(&iflock); 16609 16610 /* XXX TODO The scheduler usage in this module does not have sufficient 16611 * synchronization being done between running the scheduler and places 16612 * scheduling tasks. As it is written, any scheduled item may not run 16613 * any sooner than about 1 second, regardless of whether a sooner time 16614 * was asked for. */ 16615 16616 pthread_testcancel(); 16617 /* Wait for sched or io */ 16618 res = ast_sched_wait(sched); 16619 if ((res < 0) || (res > 1000)) 16620 res = 1000; 16621 /* If we might need to send more mailboxes, don't wait long at all.*/ 16622 if (fastrestart) 16623 res = 1; 16624 res = ast_io_wait(io, res); 16625 if (option_debug && res > 20) 16626 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 16627 ast_mutex_lock(&monlock); 16628 res = ast_sched_runq(sched); 16629 if (option_debug && res >= 20) 16630 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 16631 16632 /* Send MWI notifications to peers - static and cached realtime peers */ 16633 t = time(NULL); 16634 fastrestart = FALSE; 16635 curpeernum = 0; 16636 peer = NULL; 16637 /* Find next peer that needs mwi */ 16638 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 16639 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 16640 fastrestart = TRUE; 16641 lastpeernum = curpeernum; 16642 peer = ASTOBJ_REF(iterator); 16643 }; 16644 curpeernum++; 16645 } while (0) 16646 ); 16647 /* Send MWI to the peer */ 16648 if (peer) { 16649 ASTOBJ_WRLOCK(peer); 16650 sip_send_mwi_to_peer(peer, FALSE); 16651 ASTOBJ_UNLOCK(peer); 16652 ASTOBJ_UNREF(peer,sip_destroy_peer); 16653 } else { 16654 /* Reset where we come from */ 16655 lastpeernum = -1; 16656 } 16657 ast_mutex_unlock(&monlock); 16658 } 16659 /* Never reached */ 16660 return NULL; 16661 16662 }
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 11890 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().
11891 { 11892 char digest[1024]; 11893 11894 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 11895 return -2; 11896 11897 p->authtries++; 11898 if (option_debug > 1) 11899 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 11900 memset(digest, 0, sizeof(digest)); 11901 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 11902 /* No way to authenticate */ 11903 return -1; 11904 } 11905 /* Now we have a reply digest */ 11906 p->options->auth = digest; 11907 p->options->authheader = respheader; 11908 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 11909 }
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 11869 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().
11870 { 11871 char digest[1024]; 11872 p->authtries++; 11873 memset(digest,0,sizeof(digest)); 11874 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 11875 /* There's nothing to use for authentication */ 11876 /* No digest challenge in request */ 11877 if (sip_debug_test_pvt(p) && p->registry) 11878 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 11879 /* No old challenge */ 11880 return -1; 11881 } 11882 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 11883 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 11884 if (sip_debug_test_pvt(p) && p->registry) 11885 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 11886 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 11887 }
static void do_setnat | ( | struct sip_pvt * | p, | |
int | natflags | |||
) | [static] |
Set nat mode on the various data sockets.
Definition at line 2790 of file chan_sip.c.
References ast_log(), ast_rtp_setnat(), ast_udptl_setnat(), LOG_DEBUG, option_debug, sip_pvt::rtp, sip_pvt::udptl, and sip_pvt::vrtp.
Referenced by check_user_full(), create_addr_from_peer(), sip_alloc(), and transmit_response_using_temp().
02791 { 02792 const char *mode = natflags ? "On" : "Off"; 02793 02794 if (p->rtp) { 02795 if (option_debug) 02796 ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode); 02797 ast_rtp_setnat(p->rtp, natflags); 02798 } 02799 if (p->vrtp) { 02800 if (option_debug) 02801 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode); 02802 ast_rtp_setnat(p->vrtp, natflags); 02803 } 02804 if (p->udptl) { 02805 if (option_debug) 02806 ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode); 02807 ast_udptl_setnat(p->udptl, natflags); 02808 } 02809 }
static int does_peer_need_mwi | ( | struct sip_peer * | peer | ) | [static] |
Check whether peer needs a new MWI notification check.
Definition at line 16472 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.
16473 { 16474 time_t t = time(NULL); 16475 16476 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 16477 !peer->mwipvt) { /* We don't have a subscription */ 16478 peer->lastmsgcheck = t; /* Reset timer */ 16479 return FALSE; 16480 } 16481 16482 if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime) 16483 return TRUE; 16484 16485 return FALSE; 16486 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 10717 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
10718 { 10719 switch (mode) { 10720 case SIP_DOMAIN_AUTO: 10721 return "[Automatic]"; 10722 case SIP_DOMAIN_CONFIG: 10723 return "[Configured]"; 10724 } 10725 10726 return ""; 10727 }
static const char * dtmfmode2str | ( | int | mode | ) | const [static] |
Convert DTMF mode to printable string.
Definition at line 10497 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().
10498 { 10499 switch (mode) { 10500 case SIP_DTMF_RFC2833: 10501 return "rfc2833"; 10502 case SIP_DTMF_INFO: 10503 return "info"; 10504 case SIP_DTMF_INBAND: 10505 return "inband"; 10506 case SIP_DTMF_AUTO: 10507 return "auto"; 10508 } 10509 return "<error>"; 10510 }
static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 8165 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().
08166 { 08167 struct sip_peer *peer = (struct sip_peer *)data; 08168 08169 if (!peer) /* Hmmm. We have no peer. Weird. */ 08170 return 0; 08171 08172 memset(&peer->addr, 0, sizeof(peer->addr)); 08173 08174 destroy_association(peer); /* remove registration data from storage */ 08175 08176 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08177 register_peer_exten(peer, FALSE); /* Remove regexten */ 08178 peer->expire = -1; 08179 ast_device_state_changed("SIP/%s", peer->name); 08180 08181 /* Do we need to release this peer from memory? 08182 Only for realtime peers and autocreated peers 08183 */ 08184 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) || 08185 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 08186 struct sip_peer *peer_ptr = peer_ptr; 08187 peer_ptr = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); 08188 if (peer_ptr) { 08189 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08190 } 08191 } 08192 08193 ASTOBJ_UNREF(peer, sip_destroy_peer); 08194 08195 return 0; 08196 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 7088 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().
07089 { 07090 char stripped[SIPBUFSIZE]; 07091 char *c; 07092 07093 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 07094 c = get_in_brackets(stripped); 07095 c = strsep(&c, ";"); /* trim ; and beyond */ 07096 if (!ast_strlen_zero(c)) 07097 ast_string_field_set(p, uri, c); 07098 }
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 4333 of file chan_sip.c.
References aliases.
04334 { 04335 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 04336 static const struct cfalias { 04337 char * const fullname; 04338 char * const shortname; 04339 } aliases[] = { 04340 { "Content-Type", "c" }, 04341 { "Content-Encoding", "e" }, 04342 { "From", "f" }, 04343 { "Call-ID", "i" }, 04344 { "Contact", "m" }, 04345 { "Content-Length", "l" }, 04346 { "Subject", "s" }, 04347 { "To", "t" }, 04348 { "Supported", "k" }, 04349 { "Refer-To", "r" }, 04350 { "Referred-By", "b" }, 04351 { "Allow-Events", "u" }, 04352 { "Event", "o" }, 04353 { "Via", "v" }, 04354 { "Accept-Contact", "a" }, 04355 { "Reject-Contact", "j" }, 04356 { "Request-Disposition", "d" }, 04357 { "Session-Expires", "x" }, 04358 { "Identity", "y" }, 04359 { "Identity-Info", "n" }, 04360 }; 04361 int x; 04362 04363 for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 04364 if (!strcasecmp(aliases[x].fullname, name)) 04365 return aliases[x].shortname; 04366 04367 return _default; 04368 }
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 4695 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().
04696 { 04697 struct sip_pvt *p = NULL; 04698 char *tag = ""; /* note, tag is never NULL */ 04699 char totag[128]; 04700 char fromtag[128]; 04701 const char *callid = get_header(req, "Call-ID"); 04702 const char *from = get_header(req, "From"); 04703 const char *to = get_header(req, "To"); 04704 const char *cseq = get_header(req, "Cseq"); 04705 04706 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 04707 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 04708 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 04709 ast_strlen_zero(from) || ast_strlen_zero(cseq)) 04710 return NULL; /* Invalid packet */ 04711 04712 if (pedanticsipchecking) { 04713 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 04714 we need more to identify a branch - so we have to check branch, from 04715 and to tags to identify a call leg. 04716 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 04717 in sip.conf 04718 */ 04719 if (gettag(req, "To", totag, sizeof(totag))) 04720 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 04721 gettag(req, "From", fromtag, sizeof(fromtag)); 04722 04723 tag = (req->method == SIP_RESPONSE) ? totag : fromtag; 04724 04725 if (option_debug > 4 ) 04726 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); 04727 } 04728 04729 ast_mutex_lock(&iflock); 04730 for (p = iflist; p; p = p->next) { 04731 /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 04732 int found = FALSE; 04733 if (ast_strlen_zero(p->callid)) 04734 continue; 04735 if (req->method == SIP_REGISTER) 04736 found = (!strcmp(p->callid, callid)); 04737 else { 04738 found = !strcmp(p->callid, callid); 04739 if (pedanticsipchecking && found) { 04740 found = ast_strlen_zero(tag) || ast_strlen_zero(p->theirtag) || !ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED) || !strcmp(p->theirtag, tag); 04741 } 04742 } 04743 04744 if (option_debug > 4) 04745 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); 04746 04747 /* If we get a new request within an existing to-tag - check the to tag as well */ 04748 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 04749 if (p->tag[0] == '\0' && totag[0]) { 04750 /* We have no to tag, but they have. Wrong dialog */ 04751 found = FALSE; 04752 } else if (totag[0]) { /* Both have tags, compare them */ 04753 if (strcmp(totag, p->tag)) { 04754 found = FALSE; /* This is not our packet */ 04755 } 04756 } 04757 if (!found && option_debug > 4) 04758 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); 04759 } 04760 if (found) { 04761 /* Found the call */ 04762 ast_mutex_lock(&p->lock); 04763 ast_mutex_unlock(&iflock); 04764 return p; 04765 } 04766 } 04767 ast_mutex_unlock(&iflock); 04768 04769 /* See if the method is capable of creating a dialog */ 04770 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 04771 if (intended_method == SIP_REFER) { 04772 /* We do support REFER, but not outside of a dialog yet */ 04773 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 04774 } else if (intended_method == SIP_NOTIFY) { 04775 /* We do not support out-of-dialog NOTIFY either, 04776 like voicemail notification, so cancel that early */ 04777 transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); 04778 } else { 04779 /* Ok, time to create a new SIP dialog object, a pvt */ 04780 if ((p = sip_alloc(callid, sin, 1, intended_method))) { 04781 /* Ok, we've created a dialog, let's go and process it */ 04782 ast_mutex_lock(&p->lock); 04783 } else { 04784 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 04785 getting a dialog from sip_alloc. 04786 04787 Without a dialog we can't retransmit and handle ACKs and all that, but at least 04788 send an error message. 04789 04790 Sorry, we apologize for the inconvienience 04791 */ 04792 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 04793 if (option_debug > 3) 04794 ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 04795 } 04796 } 04797 return p; 04798 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 04799 /* A method we do not support, let's take it on the volley */ 04800 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 04801 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 04802 /* This is a request outside of a dialog that we don't know about 04803 ...never reply to an ACK! 04804 */ 04805 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 04806 } 04807 /* We do not respond to responses for dialogs that we don't know about, we just drop 04808 the session quickly */ 04809 04810 return p; 04811 }
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 2346 of file chan_sip.c.
References s.
Referenced by get_in_brackets().
02347 { 02348 char last_char = '\0'; 02349 const char *s; 02350 for (s = start; *s && s != lim; last_char = *s++) { 02351 if (*s == '"' && last_char != '\\') 02352 break; 02353 } 02354 return s; 02355 }
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 2702 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().
02703 { 02704 struct sip_peer *p = NULL; 02705 02706 if (peer) 02707 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 02708 else 02709 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); 02710 02711 if (!p && (realtime || devstate_only)) 02712 p = realtime_peer(peer, sin, devstate_only); 02713 02714 return p; 02715 }
static struct sip_auth * find_realm_authentication | ( | struct sip_auth * | authlist, | |
const char * | realm | |||
) | [static] |
Find authentication for a specific realm.
Definition at line 17302 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
17303 { 17304 struct sip_auth *a; 17305 17306 for (a = authlist; a; a = a->next) { 17307 if (!strcasecmp(a->realm, realm)) 17308 break; 17309 } 17310 17311 return a; 17312 }
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 5029 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().
05030 { 05031 const char *content_type; 05032 const char *content_length; 05033 const char *search; 05034 char *boundary; 05035 unsigned int x; 05036 int boundaryisquoted = FALSE; 05037 int found_application_sdp = FALSE; 05038 int found_end_of_headers = FALSE; 05039 05040 content_length = get_header(req, "Content-Length"); 05041 05042 if (!ast_strlen_zero(content_length)) { 05043 if (sscanf(content_length, "%ud", &x) != 1) { 05044 ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length); 05045 return 0; 05046 } 05047 05048 /* Content-Length of zero means there can't possibly be an 05049 SDP here, even if the Content-Type says there is */ 05050 if (x == 0) 05051 return 0; 05052 } 05053 05054 content_type = get_header(req, "Content-Type"); 05055 05056 /* if the body contains only SDP, this is easy */ 05057 if (!strncasecmp(content_type, "application/sdp", 15)) { 05058 req->sdp_start = 0; 05059 req->sdp_end = req->lines; 05060 return req->lines ? 1 : 0; 05061 } 05062 05063 /* if it's not multipart/mixed, there cannot be an SDP */ 05064 if (strncasecmp(content_type, "multipart/mixed", 15)) 05065 return 0; 05066 05067 /* if there is no boundary marker, it's invalid */ 05068 if ((search = strcasestr(content_type, ";boundary="))) 05069 search += 10; 05070 else if ((search = strcasestr(content_type, "; boundary="))) 05071 search += 11; 05072 else 05073 return 0; 05074 05075 if (ast_strlen_zero(search)) 05076 return 0; 05077 05078 /* If the boundary is quoted with ", remove quote */ 05079 if (*search == '\"') { 05080 search++; 05081 boundaryisquoted = TRUE; 05082 } 05083 05084 /* make a duplicate of the string, with two extra characters 05085 at the beginning */ 05086 boundary = ast_strdupa(search - 2); 05087 boundary[0] = boundary[1] = '-'; 05088 /* Remove final quote */ 05089 if (boundaryisquoted) 05090 boundary[strlen(boundary) - 1] = '\0'; 05091 05092 /* search for the boundary marker, the empty line delimiting headers from 05093 sdp part and the end boundry if it exists */ 05094 05095 for (x = 0; x < (req->lines ); x++) { 05096 if(!strncasecmp(req->line[x], boundary, strlen(boundary))){ 05097 if(found_application_sdp && found_end_of_headers){ 05098 req->sdp_end = x-1; 05099 return 1; 05100 } 05101 found_application_sdp = FALSE; 05102 } 05103 if(!strcasecmp(req->line[x], "Content-Type: application/sdp")) 05104 found_application_sdp = TRUE; 05105 05106 if(strlen(req->line[x]) == 0 ){ 05107 if(found_application_sdp && !found_end_of_headers){ 05108 req->sdp_start = x; 05109 found_end_of_headers = TRUE; 05110 } 05111 } 05112 } 05113 if(found_application_sdp && found_end_of_headers) { 05114 req->sdp_end = x; 05115 return TRUE; 05116 } 05117 return FALSE; 05118 }
static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 1697 of file chan_sip.c.
References ast_strlen_zero(), method_match(), and sip_methods.
Referenced by __sip_pretend_ack(), handle_response(), and sipsock_read().
01698 { 01699 int i, res = 0; 01700 01701 if (ast_strlen_zero(msg)) 01702 return 0; 01703 for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) { 01704 if (method_match(i, msg)) 01705 res = sip_methods[i].id; 01706 } 01707 return res; 01708 }
static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static] |
Find subscription type in array.
Definition at line 11205 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
11206 { 11207 int i; 11208 11209 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 11210 if (subscription_types[i].type == subtype) { 11211 return &subscription_types[i]; 11212 } 11213 } 11214 return &subscription_types[0]; 11215 }
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 2781 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.
02782 { 02783 struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name); 02784 if (!u && realtime) 02785 u = realtime_user(name); 02786 return u; 02787 }
static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 8544 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
08545 { 08546 struct sip_route *next; 08547 08548 while (route) { 08549 next = route->next; 08550 free(route); 08551 route = next; 08552 } 08553 }
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 12226 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), and check_sip_domain().
12227 { 12228 if (ast_strlen_zero(data)) { 12229 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 12230 return -1; 12231 } 12232 if (check_sip_domain(data, NULL, 0)) 12233 ast_copy_string(buf, data, len); 12234 else 12235 buf[0] = '\0'; 12236 return 0; 12237 }
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 12162 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.
12163 { 12164 struct sip_pvt *p; 12165 const char *content = NULL; 12166 AST_DECLARE_APP_ARGS(args, 12167 AST_APP_ARG(header); 12168 AST_APP_ARG(number); 12169 ); 12170 int i, number, start = 0; 12171 12172 if (ast_strlen_zero(data)) { 12173 ast_log(LOG_WARNING, "This function requires a header name.\n"); 12174 return -1; 12175 } 12176 12177 ast_channel_lock(chan); 12178 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 12179 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 12180 ast_channel_unlock(chan); 12181 return -1; 12182 } 12183 12184 AST_STANDARD_APP_ARGS(args, data); 12185 if (!args.number) { 12186 number = 1; 12187 } else { 12188 sscanf(args.number, "%d", &number); 12189 if (number < 1) 12190 number = 1; 12191 } 12192 12193 p = chan->tech_pvt; 12194 12195 /* If there is no private structure, this channel is no longer alive */ 12196 if (!p) { 12197 ast_channel_unlock(chan); 12198 return -1; 12199 } 12200 12201 for (i = 0; i < number; i++) 12202 content = __get_header(&p->initreq, args.header, &start); 12203 12204 if (ast_strlen_zero(content)) { 12205 ast_channel_unlock(chan); 12206 return -1; 12207 } 12208 12209 ast_copy_string(buf, content, len); 12210 ast_channel_unlock(chan); 12211 12212 return 0; 12213 }
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 12345 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.
12346 { 12347 struct sip_pvt *p; 12348 12349 *buf = 0; 12350 12351 if (!data) { 12352 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 12353 return -1; 12354 } 12355 12356 ast_channel_lock(chan); 12357 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 12358 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 12359 ast_channel_unlock(chan); 12360 return -1; 12361 } 12362 12363 p = chan->tech_pvt; 12364 12365 /* If there is no private structure, this channel is no longer alive */ 12366 if (!p) { 12367 ast_channel_unlock(chan); 12368 return -1; 12369 } 12370 12371 if (!strcasecmp(data, "peerip")) { 12372 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 12373 } else if (!strcasecmp(data, "recvip")) { 12374 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 12375 } else if (!strcasecmp(data, "from")) { 12376 ast_copy_string(buf, p->from, len); 12377 } else if (!strcasecmp(data, "uri")) { 12378 ast_copy_string(buf, p->uri, len); 12379 } else if (!strcasecmp(data, "useragent")) { 12380 ast_copy_string(buf, p->useragent, len); 12381 } else if (!strcasecmp(data, "peername")) { 12382 ast_copy_string(buf, p->peername, len); 12383 } else if (!strcasecmp(data, "t38passthrough")) { 12384 if (p->t38.state == T38_DISABLED) 12385 ast_copy_string(buf, "0", sizeof("0")); 12386 else /* T38 is offered or enabled in this call */ 12387 ast_copy_string(buf, "1", sizeof("1")); 12388 } else { 12389 ast_channel_unlock(chan); 12390 return -1; 12391 } 12392 ast_channel_unlock(chan); 12393 12394 return 0; 12395 }
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 12251 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.
12252 { 12253 struct sip_peer *peer; 12254 char *colname; 12255 12256 if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */ 12257 *colname++ = '\0'; 12258 else if ((colname = strchr(data, '|'))) 12259 *colname++ = '\0'; 12260 else 12261 colname = "ip"; 12262 12263 if (!(peer = find_peer(data, NULL, 1, 0))) 12264 return -1; 12265 12266 if (!strcasecmp(colname, "ip")) { 12267 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 12268 } else if (!strcasecmp(colname, "status")) { 12269 peer_status(peer, buf, len); 12270 } else if (!strcasecmp(colname, "language")) { 12271 ast_copy_string(buf, peer->language, len); 12272 } else if (!strcasecmp(colname, "regexten")) { 12273 ast_copy_string(buf, peer->regexten, len); 12274 } else if (!strcasecmp(colname, "limit")) { 12275 snprintf(buf, len, "%d", peer->call_limit); 12276 } else if (!strcasecmp(colname, "curcalls")) { 12277 snprintf(buf, len, "%d", peer->inUse); 12278 } else if (!strcasecmp(colname, "accountcode")) { 12279 ast_copy_string(buf, peer->accountcode, len); 12280 } else if (!strcasecmp(colname, "useragent")) { 12281 ast_copy_string(buf, peer->useragent, len); 12282 } else if (!strcasecmp(colname, "mailbox")) { 12283 ast_copy_string(buf, peer->mailbox, len); 12284 } else if (!strcasecmp(colname, "context")) { 12285 ast_copy_string(buf, peer->context, len); 12286 } else if (!strcasecmp(colname, "expire")) { 12287 snprintf(buf, len, "%d", peer->expire); 12288 } else if (!strcasecmp(colname, "dynamic")) { 12289 ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 12290 } else if (!strcasecmp(colname, "callerid_name")) { 12291 ast_copy_string(buf, peer->cid_name, len); 12292 } else if (!strcasecmp(colname, "callerid_num")) { 12293 ast_copy_string(buf, peer->cid_num, len); 12294 } else if (!strcasecmp(colname, "codecs")) { 12295 ast_getformatname_multiple(buf, len -1, peer->capability); 12296 } else if (!strncasecmp(colname, "codec[", 6)) { 12297 char *codecnum; 12298 int index = 0, codec = 0; 12299 12300 codecnum = colname + 6; /* move past the '[' */ 12301 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 12302 index = atoi(codecnum); 12303 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 12304 ast_copy_string(buf, ast_getformatname(codec), len); 12305 } else { 12306 buf[0] = '\0'; 12307 } 12308 } else { 12309 buf[0] = '\0'; 12310 } 12311 12312 ASTOBJ_UNREF(peer, sip_destroy_peer); 12313 12314 return 0; 12315 }
static char * generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 4523 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), and build_callid_registry().
04524 { 04525 long val[4]; 04526 int x; 04527 04528 for (x=0; x<4; x++) 04529 val[x] = ast_random(); 04530 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 04531 04532 return buf; 04533 }
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 9568 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().
09569 { 09570 char tmp[256] = "", *c, *a; 09571 struct sip_request *req = oreq ? oreq : &p->initreq; 09572 struct sip_refer *referdata = NULL; 09573 const char *transfer_context = NULL; 09574 09575 if (!p->refer && !sip_refer_allocate(p)) 09576 return -1; 09577 09578 referdata = p->refer; 09579 09580 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 09581 c = get_in_brackets(tmp); 09582 09583 if (pedanticsipchecking) 09584 ast_uri_decode(c); 09585 09586 if (strncasecmp(c, "sip:", 4)) { 09587 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 09588 return -1; 09589 } 09590 c += 4; 09591 if ((a = strchr(c, ';'))) /* Remove arguments */ 09592 *a = '\0'; 09593 09594 if ((a = strchr(c, '@'))) { /* Separate Domain */ 09595 *a++ = '\0'; 09596 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 09597 } 09598 09599 if (sip_debug_test_pvt(p)) 09600 ast_verbose("Looking for %s in %s\n", c, p->context); 09601 09602 if (p->owner) /* Mimic behaviour in res_features.c */ 09603 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 09604 09605 /* By default, use the context in the channel sending the REFER */ 09606 if (ast_strlen_zero(transfer_context)) { 09607 transfer_context = S_OR(p->owner->macrocontext, 09608 S_OR(p->context, default_context)); 09609 } 09610 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 09611 /* This is a blind transfer */ 09612 if (option_debug) 09613 ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 09614 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 09615 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 09616 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 09617 referdata->refer_call = NULL; 09618 /* Set new context */ 09619 ast_string_field_set(p, context, transfer_context); 09620 return 0; 09621 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 09622 return 1; 09623 } 09624 09625 return -1; 09626 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
Get a specific line from the message body.
Definition at line 4317 of file chan_sip.c.
References get_body_by_line(), len(), sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
04318 { 04319 int x; 04320 int len = strlen(name); 04321 char *r; 04322 04323 for (x = 0; x < req->lines; x++) { 04324 r = get_body_by_line(req->line[x], name, len); 04325 if (r[0] != '\0') 04326 return r; 04327 } 04328 04329 return ""; 04330 }
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 4283 of file chan_sip.c.
References ast_skip_blanks().
Referenced by get_body(), and get_sdp_iterate().
04284 { 04285 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') 04286 return ast_skip_blanks(line + nameLen + 1); 04287 04288 return ""; 04289 }
static char * get_calleridname | ( | const char * | input, | |
char * | output, | |||
size_t | outputsize | |||
) | [static] |
Get caller id name from SIP headers.
Definition at line 9680 of file chan_sip.c.
References ast_copy_string(), and ast_skip_blanks().
Referenced by check_user_full().
09681 { 09682 const char *end = strchr(input,'<'); /* first_bracket */ 09683 const char *tmp = strchr(input,'"'); /* first quote */ 09684 int bytes = 0; 09685 int maxbytes = outputsize - 1; 09686 09687 if (!end || end == input) /* we require a part in brackets */ 09688 return NULL; 09689 09690 end--; /* move just before "<" */ 09691 09692 if (tmp && tmp <= end) { 09693 /* The quote (tmp) precedes the bracket (end+1). 09694 * Find the matching quote and return the content. 09695 */ 09696 end = strchr(tmp+1, '"'); 09697 if (!end) 09698 return NULL; 09699 bytes = (int) (end - tmp); 09700 /* protect the output buffer */ 09701 if (bytes > maxbytes) 09702 bytes = maxbytes; 09703 ast_copy_string(output, tmp + 1, bytes); 09704 } else { 09705 /* No quoted string, or it is inside brackets. */ 09706 /* clear the empty characters in the begining*/ 09707 input = ast_skip_blanks(input); 09708 /* clear the empty characters in the end */ 09709 while(*end && *end < 33 && end > input) 09710 end--; 09711 if (end >= input) { 09712 bytes = (int) (end - input) + 2; 09713 /* protect the output buffer */ 09714 if (bytes > maxbytes) 09715 bytes = maxbytes; 09716 ast_copy_string(output, input, bytes); 09717 } else 09718 return NULL; 09719 } 09720 return output; 09721 }
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 9218 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().
09219 { 09220 char tmp[256] = "", *uri, *a; 09221 char tmpf[256] = "", *from; 09222 struct sip_request *req; 09223 char *colon; 09224 char *decoded_uri; 09225 09226 req = oreq; 09227 if (!req) 09228 req = &p->initreq; 09229 09230 /* Find the request URI */ 09231 if (req->rlPart2) 09232 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 09233 09234 if (pedanticsipchecking) 09235 ast_uri_decode(tmp); 09236 09237 uri = get_in_brackets(tmp); 09238 09239 if (strncasecmp(uri, "sip:", 4)) { 09240 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 09241 return -1; 09242 } 09243 uri += 4; 09244 09245 /* Now find the From: caller ID and name */ 09246 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 09247 if (!ast_strlen_zero(tmpf)) { 09248 if (pedanticsipchecking) 09249 ast_uri_decode(tmpf); 09250 from = get_in_brackets(tmpf); 09251 } else { 09252 from = NULL; 09253 } 09254 09255 if (!ast_strlen_zero(from)) { 09256 if (strncasecmp(from, "sip:", 4)) { 09257 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 09258 return -1; 09259 } 09260 from += 4; 09261 if ((a = strchr(from, '@'))) 09262 *a++ = '\0'; 09263 else 09264 a = from; /* just a domain */ 09265 from = strsep(&from, ";"); /* Remove userinfo options */ 09266 a = strsep(&a, ";"); /* Remove URI options */ 09267 ast_string_field_set(p, fromdomain, a); 09268 } 09269 09270 /* Skip any options and find the domain */ 09271 09272 /* Get the target domain */ 09273 if ((a = strchr(uri, '@'))) { 09274 *a++ = '\0'; 09275 } else { /* No username part */ 09276 a = uri; 09277 uri = "s"; /* Set extension to "s" */ 09278 } 09279 colon = strchr(a, ':'); /* Remove :port */ 09280 if (colon) 09281 *colon = '\0'; 09282 09283 uri = strsep(&uri, ";"); /* Remove userinfo options */ 09284 a = strsep(&a, ";"); /* Remove URI options */ 09285 09286 ast_string_field_set(p, domain, a); 09287 09288 if (!AST_LIST_EMPTY(&domain_list)) { 09289 char domain_context[AST_MAX_EXTENSION]; 09290 09291 domain_context[0] = '\0'; 09292 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 09293 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 09294 if (option_debug) 09295 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 09296 return -2; 09297 } 09298 } 09299 /* If we have a context defined, overwrite the original context */ 09300 if (!ast_strlen_zero(domain_context)) 09301 ast_string_field_set(p, context, domain_context); 09302 } 09303 09304 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 09305 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) 09306 ast_string_field_set(p, context, p->subscribecontext); 09307 09308 if (sip_debug_test_pvt(p)) 09309 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 09310 09311 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 09312 if (req->method == SIP_SUBSCRIBE) { 09313 char hint[AST_MAX_EXTENSION]; 09314 return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1); 09315 } else { 09316 decoded_uri = ast_strdupa(uri); 09317 ast_uri_decode(decoded_uri); 09318 /* Check the dialplan for the username part of the request URI, 09319 the domain will be stored in the SIPDOMAIN variable 09320 Since extensions.conf can have unescaped characters, try matching a decoded 09321 uri in addition to the non-decoded uri 09322 Return 0 if we have a matching extension */ 09323 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)) || 09324 !strcmp(decoded_uri, ast_pickup_ext())) { 09325 if (!oreq) 09326 ast_string_field_set(p, exten, decoded_uri); 09327 return 0; 09328 } 09329 } 09330 09331 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 09332 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 09333 ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))) || 09334 !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri))) { 09335 return 1; 09336 } 09337 09338 return -1; 09339 }
static const char * get_header | ( | const struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get header from SIP request.
Definition at line 4406 of file chan_sip.c.
References __get_header().
04407 { 04408 int start = 0; 04409 return __get_header(req, name, &start); 04410 }
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 2368 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().
02369 { 02370 const char *parse = tmp; 02371 char *first_bracket; 02372 02373 /* 02374 * Skip any quoted text until we find the part in brackets. 02375 * On any error give up and return the full string. 02376 */ 02377 while ( (first_bracket = strchr(parse, '<')) ) { 02378 char *first_quote = strchr(parse, '"'); 02379 02380 if (!first_quote || first_quote > first_bracket) 02381 break; /* no need to look at quoted part */ 02382 /* the bracket is within quotes, so ignore it */ 02383 parse = find_closing_quote(first_quote + 1, NULL); 02384 if (!*parse) { /* not found, return full string ? */ 02385 /* XXX or be robust and return in-bracket part ? */ 02386 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 02387 break; 02388 } 02389 parse++; 02390 } 02391 if (first_bracket) { 02392 char *second_bracket = strchr(first_bracket + 1, '>'); 02393 if (second_bracket) { 02394 *second_bracket = '\0'; 02395 tmp = first_bracket + 1; 02396 } else { 02397 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 02398 } 02399 } 02400 return tmp; 02401 }
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 10090 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_notify(), and receive_message().
10091 { 10092 int x; 10093 int y; 10094 10095 buf[0] = '\0'; 10096 y = len - strlen(buf) - 5; 10097 if (y < 0) 10098 y = 0; 10099 for (x=0;x<req->lines;x++) { 10100 strncat(buf, req->line[x], y); /* safe */ 10101 y -= strlen(req->line[x]) + 1; 10102 if (y < 0) 10103 y = 0; 10104 if (y != 0) 10105 strcat(buf, "\n"); /* safe */ 10106 } 10107 return 0; 10108 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Get referring dnis.
Definition at line 9189 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().
09190 { 09191 char tmp[256], *c, *a; 09192 struct sip_request *req; 09193 09194 req = oreq; 09195 if (!req) 09196 req = &p->initreq; 09197 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 09198 if (ast_strlen_zero(tmp)) 09199 return 0; 09200 c = get_in_brackets(tmp); 09201 if (strncasecmp(c, "sip:", 4)) { 09202 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 09203 return -1; 09204 } 09205 c += 4; 09206 a = c; 09207 strsep(&a, "@;"); /* trim anything after @ or ; */ 09208 if (sip_debug_test_pvt(p)) 09209 ast_verbose("RDNIS is %s\n", c); 09210 ast_string_field_set(p, rdnis, c); 09211 09212 return 0; 09213 }
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 9405 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().
09406 { 09407 09408 const char *p_referred_by = NULL; 09409 char *h_refer_to = NULL; 09410 char *h_referred_by = NULL; 09411 char *refer_to; 09412 const char *p_refer_to; 09413 char *referred_by_uri = NULL; 09414 char *ptr; 09415 struct sip_request *req = NULL; 09416 const char *transfer_context = NULL; 09417 struct sip_refer *referdata; 09418 09419 09420 req = outgoing_req; 09421 referdata = transferer->refer; 09422 09423 if (!req) 09424 req = &transferer->initreq; 09425 09426 p_refer_to = get_header(req, "Refer-To"); 09427 if (ast_strlen_zero(p_refer_to)) { 09428 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 09429 return -2; /* Syntax error */ 09430 } 09431 h_refer_to = ast_strdupa(p_refer_to); 09432 refer_to = get_in_brackets(h_refer_to); 09433 if (pedanticsipchecking) 09434 ast_uri_decode(refer_to); 09435 09436 if (strncasecmp(refer_to, "sip:", 4)) { 09437 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 09438 return -3; 09439 } 09440 refer_to += 4; /* Skip sip: */ 09441 09442 /* Get referred by header if it exists */ 09443 p_referred_by = get_header(req, "Referred-By"); 09444 if (!ast_strlen_zero(p_referred_by)) { 09445 char *lessthan; 09446 h_referred_by = ast_strdupa(p_referred_by); 09447 if (pedanticsipchecking) 09448 ast_uri_decode(h_referred_by); 09449 09450 /* Store referrer's caller ID name */ 09451 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 09452 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 09453 *(lessthan - 1) = '\0'; /* Space */ 09454 } 09455 09456 referred_by_uri = get_in_brackets(h_referred_by); 09457 if(strncasecmp(referred_by_uri, "sip:", 4)) { 09458 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 09459 referred_by_uri = (char *) NULL; 09460 } else { 09461 referred_by_uri += 4; /* Skip sip: */ 09462 } 09463 } 09464 09465 /* Check for arguments in the refer_to header */ 09466 if ((ptr = strcasestr(refer_to, "replaces="))) { 09467 char *to = NULL, *from = NULL; 09468 09469 /* This is an attended transfer */ 09470 referdata->attendedtransfer = 1; 09471 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 09472 ast_uri_decode(referdata->replaces_callid); 09473 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 09474 *ptr++ = '\0'; 09475 } 09476 09477 if (ptr) { 09478 /* Find the different tags before we destroy the string */ 09479 to = strcasestr(ptr, "to-tag="); 09480 from = strcasestr(ptr, "from-tag="); 09481 } 09482 09483 /* Grab the to header */ 09484 if (to) { 09485 ptr = to + 7; 09486 if ((to = strchr(ptr, '&'))) 09487 *to = '\0'; 09488 if ((to = strchr(ptr, ';'))) 09489 *to = '\0'; 09490 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 09491 } 09492 09493 if (from) { 09494 ptr = from + 9; 09495 if ((to = strchr(ptr, '&'))) 09496 *to = '\0'; 09497 if ((to = strchr(ptr, ';'))) 09498 *to = '\0'; 09499 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 09500 } 09501 09502 if (option_debug > 1) { 09503 if (!pedanticsipchecking) 09504 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 09505 else 09506 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>" ); 09507 } 09508 } 09509 09510 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 09511 char *urioption = NULL, *domain; 09512 *ptr++ = '\0'; 09513 09514 if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */ 09515 *urioption++ = '\0'; 09516 09517 domain = ptr; 09518 if ((ptr = strchr(domain, ':'))) /* Remove :port */ 09519 *ptr = '\0'; 09520 09521 /* Save the domain for the dial plan */ 09522 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 09523 if (urioption) 09524 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 09525 } 09526 09527 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 09528 *ptr = '\0'; 09529 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 09530 09531 if (referred_by_uri) { 09532 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 09533 *ptr = '\0'; 09534 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 09535 } else { 09536 referdata->referred_by[0] = '\0'; 09537 } 09538 09539 /* Determine transfer context */ 09540 if (transferer->owner) /* Mimic behaviour in res_features.c */ 09541 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 09542 09543 /* By default, use the context in the channel sending the REFER */ 09544 if (ast_strlen_zero(transfer_context)) { 09545 transfer_context = S_OR(transferer->owner->macrocontext, 09546 S_OR(transferer->context, default_context)); 09547 } 09548 09549 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 09550 09551 /* Either an existing extension or the parking extension */ 09552 if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 09553 if (sip_debug_test_pvt(transferer)) { 09554 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 09555 } 09556 /* We are ready to transfer to the extension */ 09557 return 0; 09558 } 09559 if (sip_debug_test_pvt(transferer)) 09560 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 09561 09562 /* Failure, we can't find this extension */ 09563 return -1; 09564 }
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 9727 of file chan_sip.c.
References ast_copy_string(), and AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
09728 { 09729 char *start; 09730 char *end; 09731 09732 start = strchr(input,':'); 09733 if (!start) { 09734 output[0] = '\0'; 09735 return 0; 09736 } 09737 start++; 09738 09739 /* we found "number" */ 09740 ast_copy_string(output,start,maxlen); 09741 output[maxlen-1] = '\0'; 09742 09743 end = strchr(output,'@'); 09744 if (end) 09745 *end = '\0'; 09746 else 09747 output[0] = '\0'; 09748 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 09749 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 09750 09751 return 0; 09752 }
static const char * get_sdp | ( | struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get a line from an SDP message body.
Definition at line 4309 of file chan_sip.c.
References get_sdp_iterate().
04310 { 04311 int dummy = 0; 04312 04313 return get_sdp_iterate(&dummy, req, name); 04314 }
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 4295 of file chan_sip.c.
References get_body_by_line(), len(), and sip_request::line.
04296 { 04297 int len = strlen(name); 04298 04299 while (*start < req->sdp_end) { 04300 const char *r = get_body_by_line(req->line[(*start)++], name, len); 04301 if (r[0] != '\0') 04302 return r; 04303 } 04304 04305 return ""; 04306 }
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 9343 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().
09344 { 09345 struct sip_pvt *sip_pvt_ptr; 09346 09347 ast_mutex_lock(&iflock); 09348 09349 if (option_debug > 3 && totag) 09350 ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 09351 09352 /* Search interfaces and find the match */ 09353 for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 09354 if (!strcmp(sip_pvt_ptr->callid, callid)) { 09355 int match = 1; 09356 09357 /* Go ahead and lock it (and its owner) before returning */ 09358 ast_mutex_lock(&sip_pvt_ptr->lock); 09359 09360 /* Check if tags match. If not, this is not the call we want 09361 (With a forking SIP proxy, several call legs share the 09362 call id, but have different tags) 09363 */ 09364 if (pedanticsipchecking) { 09365 const char *pvt_fromtag, *pvt_totag; 09366 09367 if (ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_OUTGOING_CALL)) { 09368 /* Outgoing call tags : from is "our", to is "their" */ 09369 pvt_fromtag = sip_pvt_ptr->tag ; 09370 pvt_totag = sip_pvt_ptr->theirtag ; 09371 } else { 09372 /* Incoming call tags : from is "their", to is "our" */ 09373 pvt_fromtag = sip_pvt_ptr->theirtag ; 09374 pvt_totag = sip_pvt_ptr->tag ; 09375 } 09376 if (ast_strlen_zero(fromtag) || strcmp(fromtag, pvt_fromtag) || (!ast_strlen_zero(totag) && strcmp(totag, pvt_totag))) 09377 match = 0; 09378 } 09379 09380 if (!match) { 09381 ast_mutex_unlock(&sip_pvt_ptr->lock); 09382 continue; 09383 } 09384 09385 if (option_debug > 3 && totag) 09386 ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n", 09387 ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_OUTGOING_CALL) ? "OUTGOING": "INCOMING", 09388 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 09389 09390 /* deadlock avoidance... */ 09391 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 09392 DEADLOCK_AVOIDANCE(&sip_pvt_ptr->lock); 09393 } 09394 break; 09395 } 09396 } 09397 ast_mutex_unlock(&iflock); 09398 if (option_debug > 3 && !sip_pvt_ptr) 09399 ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 09400 return sip_pvt_ptr; 09401 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 13807 of file chan_sip.c.
References ast_copy_string(), and get_header().
Referenced by find_call(), handle_request(), handle_request_subscribe(), and handle_response().
13808 { 13809 const char *thetag; 13810 13811 if (!tagbuf) 13812 return NULL; 13813 tagbuf[0] = '\0'; /* reset the buffer */ 13814 thetag = get_header(req, header); 13815 thetag = strcasestr(thetag, ";tag="); 13816 if (thetag) { 13817 thetag += 5; 13818 ast_copy_string(tagbuf, thetag, tagbufsize); 13819 return strsep(&tagbuf, ";"); 13820 } 13821 return NULL; 13822 }
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 17051 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().
17052 { 17053 int res = 1; 17054 17055 if (!strcasecmp(v->name, "trustrpid")) { 17056 ast_set_flag(&mask[0], SIP_TRUSTRPID); 17057 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 17058 } else if (!strcasecmp(v->name, "sendrpid")) { 17059 ast_set_flag(&mask[0], SIP_SENDRPID); 17060 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 17061 } else if (!strcasecmp(v->name, "g726nonstandard")) { 17062 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 17063 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 17064 } else if (!strcasecmp(v->name, "useclientcode")) { 17065 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 17066 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 17067 } else if (!strcasecmp(v->name, "dtmfmode")) { 17068 ast_set_flag(&mask[0], SIP_DTMF); 17069 ast_clear_flag(&flags[0], SIP_DTMF); 17070 if (!strcasecmp(v->value, "inband")) 17071 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 17072 else if (!strcasecmp(v->value, "rfc2833")) 17073 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 17074 else if (!strcasecmp(v->value, "info")) 17075 ast_set_flag(&flags[0], SIP_DTMF_INFO); 17076 else if (!strcasecmp(v->value, "auto")) 17077 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 17078 else { 17079 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 17080 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 17081 } 17082 } else if (!strcasecmp(v->name, "nat")) { 17083 ast_set_flag(&mask[0], SIP_NAT); 17084 ast_clear_flag(&flags[0], SIP_NAT); 17085 if (!strcasecmp(v->value, "never")) 17086 ast_set_flag(&flags[0], SIP_NAT_NEVER); 17087 else if (!strcasecmp(v->value, "route")) 17088 ast_set_flag(&flags[0], SIP_NAT_ROUTE); 17089 else if (ast_true(v->value)) 17090 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 17091 else 17092 ast_set_flag(&flags[0], SIP_NAT_RFC3581); 17093 } else if (!strcasecmp(v->name, "canreinvite")) { 17094 ast_set_flag(&mask[0], SIP_REINVITE); 17095 ast_clear_flag(&flags[0], SIP_REINVITE); 17096 if(ast_true(v->value)) { 17097 ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT); 17098 } else if (!ast_false(v->value)) { 17099 char buf[64]; 17100 char *word, *next = buf; 17101 17102 ast_copy_string(buf, v->value, sizeof(buf)); 17103 while ((word = strsep(&next, ","))) { 17104 if(!strcasecmp(word, "update")) { 17105 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 17106 } else if(!strcasecmp(word, "nonat")) { 17107 ast_set_flag(&flags[0], SIP_CAN_REINVITE); 17108 ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT); 17109 } else { 17110 ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno); 17111 } 17112 } 17113 } 17114 } else if (!strcasecmp(v->name, "insecure")) { 17115 ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 17116 ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 17117 set_insecure_flags(flags, v->value, v->lineno); 17118 } else if (!strcasecmp(v->name, "progressinband")) { 17119 ast_set_flag(&mask[0], SIP_PROG_INBAND); 17120 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 17121 if (ast_true(v->value)) 17122 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 17123 else if (strcasecmp(v->value, "never")) 17124 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 17125 } else if (!strcasecmp(v->name, "promiscredir")) { 17126 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 17127 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 17128 } else if (!strcasecmp(v->name, "videosupport")) { 17129 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 17130 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 17131 } else if (!strcasecmp(v->name, "allowoverlap")) { 17132 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 17133 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 17134 } else if (!strcasecmp(v->name, "allowsubscribe")) { 17135 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 17136 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 17137 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 17138 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 17139 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 17140 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 17141 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 17142 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 17143 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 17144 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 17145 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 17146 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 17147 #endif 17148 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 17149 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 17150 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 17151 } else if (!strcasecmp(v->name, "buggymwi")) { 17152 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 17153 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 17154 } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { 17155 ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); 17156 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); 17157 } else 17158 res = 0; 17159 17160 return res; 17161 }
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 13992 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().
13993 { 13994 struct ast_frame *f; 13995 int earlyreplace = 0; 13996 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 13997 struct ast_channel *c = p->owner; /* Our incoming call */ 13998 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 13999 struct ast_channel *targetcall; /* The bridge to the take-over target */ 14000 14001 /* Check if we're in ring state */ 14002 if (replacecall->_state == AST_STATE_RING) 14003 earlyreplace = 1; 14004 14005 /* Check if we have a bridge */ 14006 if (!(targetcall = ast_bridged_channel(replacecall))) { 14007 /* We have no bridge */ 14008 if (!earlyreplace) { 14009 if (option_debug > 1) 14010 ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 14011 oneleggedreplace = 1; 14012 } 14013 } 14014 if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING) 14015 ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n"); 14016 14017 if (option_debug > 3) { 14018 if (targetcall) 14019 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); 14020 else 14021 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 14022 } 14023 14024 if (ignore) { 14025 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 14026 /* We should answer something here. If we are here, the 14027 call we are replacing exists, so an accepted 14028 can't harm */ 14029 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 14030 /* Do something more clever here */ 14031 ast_channel_unlock(c); 14032 ast_mutex_unlock(&p->refer->refer_call->lock); 14033 return 1; 14034 } 14035 if (!c) { 14036 /* What to do if no channel ??? */ 14037 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 14038 transmit_response_reliable(p, "503 Service Unavailable", req); 14039 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 14040 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14041 ast_mutex_unlock(&p->refer->refer_call->lock); 14042 return 1; 14043 } 14044 append_history(p, "Xfer", "INVITE/Replace received"); 14045 /* We have three channels to play with 14046 channel c: New incoming call 14047 targetcall: Call from PBX to target 14048 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 14049 replacecall: The owner of the previous 14050 We need to masq C into refer_call to connect to 14051 targetcall; 14052 If we are talking to internal audio stream, target call is null. 14053 */ 14054 14055 /* Fake call progress */ 14056 transmit_response(p, "100 Trying", req); 14057 ast_setstate(c, AST_STATE_RING); 14058 14059 /* Masquerade the new call into the referred call to connect to target call 14060 Targetcall is not touched by the masq */ 14061 14062 /* Answer the incoming call and set channel to UP state */ 14063 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 14064 14065 ast_setstate(c, AST_STATE_UP); 14066 14067 /* Stop music on hold and other generators */ 14068 ast_quiet_chan(replacecall); 14069 ast_quiet_chan(targetcall); 14070 if (option_debug > 3) 14071 ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 14072 /* Unlock clone, but not original (replacecall) */ 14073 if (!oneleggedreplace) 14074 ast_channel_unlock(c); 14075 14076 /* Unlock PVT */ 14077 ast_mutex_unlock(&p->refer->refer_call->lock); 14078 14079 /* Make sure that the masq does not free our PVT for the old call */ 14080 if (! earlyreplace && ! oneleggedreplace ) 14081 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14082 14083 /* Prepare the masquerade - if this does not happen, we will be gone */ 14084 if(ast_channel_masquerade(replacecall, c)) 14085 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 14086 else if (option_debug > 3) 14087 ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 14088 14089 /* The masquerade will happen as soon as someone reads a frame from the channel */ 14090 14091 /* C should now be in place of replacecall */ 14092 /* ast_read needs to lock channel */ 14093 ast_channel_unlock(c); 14094 14095 if (earlyreplace || oneleggedreplace ) { 14096 /* Force the masq to happen */ 14097 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 14098 ast_frfree(f); 14099 f = NULL; 14100 if (option_debug > 3) 14101 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from RING channel!\n"); 14102 } else { 14103 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from RING channel \n"); 14104 } 14105 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 14106 if (!oneleggedreplace) 14107 ast_channel_unlock(replacecall); 14108 } else { /* Bridged call, UP channel */ 14109 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 14110 /* Masq ok */ 14111 ast_frfree(f); 14112 f = NULL; 14113 if (option_debug > 2) 14114 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from channel! Masq done.\n"); 14115 } else { 14116 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from channel. Transfer failed\n"); 14117 } 14118 ast_channel_unlock(replacecall); 14119 } 14120 ast_mutex_unlock(&p->refer->refer_call->lock); 14121 14122 ast_setstate(c, AST_STATE_DOWN); 14123 if (option_debug > 3) { 14124 struct ast_channel *test; 14125 ast_log(LOG_DEBUG, "After transfer:----------------------------\n"); 14126 ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 14127 if (replacecall) 14128 ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 14129 if (p->owner) { 14130 ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 14131 test = ast_bridged_channel(p->owner); 14132 if (test) 14133 ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 14134 else 14135 ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n"); 14136 } else 14137 ast_log(LOG_DEBUG, " -- No channel yet \n"); 14138 ast_log(LOG_DEBUG, "End After transfer:----------------------------\n"); 14139 } 14140 14141 ast_channel_unlock(p->owner); /* Unlock new owner */ 14142 if (!oneleggedreplace) 14143 ast_mutex_unlock(&p->lock); /* Unlock SIP structure */ 14144 14145 /* The call should be down with no ast_channel, so hang it up */ 14146 c->tech_pvt = NULL; 14147 ast_hangup(c); 14148 return 0; 14149 }
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 15997 of file chan_sip.c.
References __sip_ack(), append_history, ast_inet_ntoa(), ast_log(), ast_set_flag, ast_skip_blanks(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), check_pendings(), debug, DEFAULT_TRANS_TIMEOUT, extract_uri(), FALSE, find_sdp(), FLAG_RESPONSE, sip_pvt::flags, get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), sip_request::header, sip_request::headers, cfsip_methods::id, sip_pvt::initreq, INV_TERMINATED, len(), LOG_DEBUG, LOG_ERROR, LOG_NOTICE, sip_request::method, option_debug, process_sdp(), sip_request::rlPart1, sip_request::rlPart2, SIP_ACK, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_debug_test_pvt(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_PKT_IGNORE_REQ, SIP_PKT_IGNORE_RESP, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_scheddestroy(), SIP_SUBSCRIBE, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), TRUE, and sip_pvt::useragent.
15998 { 15999 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 16000 relatively static */ 16001 const char *cmd; 16002 const char *cseq; 16003 const char *useragent; 16004 int seqno; 16005 int len; 16006 int ignore = FALSE; 16007 int respid; 16008 int res = 0; 16009 int debug = sip_debug_test_pvt(p); 16010 char *e; 16011 int error = 0; 16012 16013 /* Get Method and Cseq */ 16014 cseq = get_header(req, "Cseq"); 16015 cmd = req->header[0]; 16016 16017 /* Must have Cseq */ 16018 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 16019 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 16020 error = 1; 16021 } 16022 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 16023 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 16024 error = 1; 16025 } 16026 if (error) { 16027 if (!p->initreq.headers) /* New call */ 16028 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 16029 return -1; 16030 } 16031 /* Get the command XXX */ 16032 16033 cmd = req->rlPart1; 16034 e = req->rlPart2; 16035 16036 /* Save useragent of the client */ 16037 useragent = get_header(req, "User-Agent"); 16038 if (!ast_strlen_zero(useragent)) 16039 ast_string_field_set(p, useragent, useragent); 16040 16041 /* Find out SIP method for incoming request */ 16042 if (req->method == SIP_RESPONSE) { /* Response to our request */ 16043 /* Response to our request -- Do some sanity checks */ 16044 if (!p->initreq.headers) { 16045 if (option_debug) 16046 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 16047 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16048 return 0; 16049 } else if (p->ocseq && (p->ocseq < seqno) && (seqno != p->lastnoninvite)) { 16050 if (option_debug) 16051 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 16052 return -1; 16053 } else if (p->ocseq && (p->ocseq != seqno) && (seqno != p->lastnoninvite)) { 16054 /* ignore means "don't do anything with it" but still have to 16055 respond appropriately */ 16056 ignore = TRUE; 16057 ast_set_flag(req, SIP_PKT_IGNORE); 16058 ast_set_flag(req, SIP_PKT_IGNORE_RESP); 16059 append_history(p, "Ignore", "Ignoring this retransmit\n"); 16060 } else if (e) { 16061 e = ast_skip_blanks(e); 16062 if (sscanf(e, "%d %n", &respid, &len) != 1) { 16063 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 16064 } else { 16065 if (respid <= 0) { 16066 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 16067 return 0; 16068 } 16069 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 16070 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 16071 extract_uri(p, req); 16072 handle_response(p, respid, e + len, req, ignore, seqno); 16073 } 16074 } 16075 return 0; 16076 } 16077 16078 /* New SIP request coming in 16079 (could be new request in existing SIP dialog as well...) 16080 */ 16081 16082 p->method = req->method; /* Find out which SIP method they are using */ 16083 if (option_debug > 3) 16084 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 16085 16086 if (p->icseq && (p->icseq > seqno) ) { 16087 if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) { 16088 if (option_debug > 2) 16089 ast_log(LOG_DEBUG, "Got CANCEL or ACK on INVITE with transactions in between.\n"); 16090 } else { 16091 if (option_debug) 16092 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 16093 if (req->method != SIP_ACK) 16094 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 16095 return -1; 16096 } 16097 } else if (p->icseq && 16098 p->icseq == seqno && 16099 req->method != SIP_ACK && 16100 (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) { 16101 /* ignore means "don't do anything with it" but still have to 16102 respond appropriately. We do this if we receive a repeat of 16103 the last sequence number */ 16104 ignore = 2; 16105 ast_set_flag(req, SIP_PKT_IGNORE); 16106 ast_set_flag(req, SIP_PKT_IGNORE_REQ); 16107 if (option_debug > 2) 16108 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 16109 } 16110 16111 if (seqno >= p->icseq) 16112 /* Next should follow monotonically (but not necessarily 16113 incrementally -- thanks again to the genius authors of SIP -- 16114 increasing */ 16115 p->icseq = seqno; 16116 16117 /* Find their tag if we haven't got it */ 16118 if (ast_strlen_zero(p->theirtag)) { 16119 char tag[128]; 16120 16121 gettag(req, "From", tag, sizeof(tag)); 16122 ast_string_field_set(p, theirtag, tag); 16123 } 16124 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 16125 16126 if (pedanticsipchecking) { 16127 /* If this is a request packet without a from tag, it's not 16128 correct according to RFC 3261 */ 16129 /* Check if this a new request in a new dialog with a totag already attached to it, 16130 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 16131 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 16132 /* If this is a first request and it got a to-tag, it is not for us */ 16133 if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) { 16134 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 16135 /* Will cease to exist after ACK */ 16136 } else if (req->method != SIP_ACK) { 16137 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 16138 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16139 } 16140 return res; 16141 } 16142 } 16143 16144 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 16145 transmit_response(p, "400 Bad request", req); 16146 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16147 return -1; 16148 } 16149 16150 /* Handle various incoming SIP methods in requests */ 16151 switch (p->method) { 16152 case SIP_OPTIONS: 16153 res = handle_request_options(p, req); 16154 break; 16155 case SIP_INVITE: 16156 res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock); 16157 break; 16158 case SIP_REFER: 16159 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 16160 break; 16161 case SIP_CANCEL: 16162 res = handle_request_cancel(p, req); 16163 break; 16164 case SIP_BYE: 16165 res = handle_request_bye(p, req); 16166 break; 16167 case SIP_MESSAGE: 16168 res = handle_request_message(p, req); 16169 break; 16170 case SIP_SUBSCRIBE: 16171 res = handle_request_subscribe(p, req, sin, seqno, e); 16172 break; 16173 case SIP_REGISTER: 16174 res = handle_request_register(p, req, sin, e); 16175 break; 16176 case SIP_INFO: 16177 if (ast_test_flag(req, SIP_PKT_DEBUG)) 16178 ast_verbose("Receiving INFO!\n"); 16179 if (!ignore) 16180 handle_request_info(p, req); 16181 else /* if ignoring, transmit response */ 16182 transmit_response(p, "200 OK", req); 16183 break; 16184 case SIP_NOTIFY: 16185 res = handle_request_notify(p, req, sin, seqno, e); 16186 break; 16187 case SIP_ACK: 16188 /* Make sure we don't ignore this */ 16189 if (seqno == p->pendinginvite) { 16190 p->invitestate = INV_TERMINATED; 16191 p->pendinginvite = 0; 16192 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 16193 if (find_sdp(req)) { 16194 if (process_sdp(p, req)) 16195 return -1; 16196 } 16197 check_pendings(p); 16198 } 16199 /* Got an ACK that we did not match. Ignore silently */ 16200 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 16201 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16202 break; 16203 default: 16204 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 16205 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 16206 cmd, ast_inet_ntoa(p->sa.sin_addr)); 16207 /* If this is some new method, and we don't have a call, destroy it now */ 16208 if (!p->initreq.headers) 16209 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 16210 break; 16211 } 16212 return res; 16213 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 15556 of file chan_sip.c.
References __sip_pretend_ack(), append_history, ast_async_goto(), ast_bridged_channel(), ast_clear_flag, AST_CONTROL_UNHOLD, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_rtp_get_quality(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, check_via(), context, sip_pvt::context, copy_request(), DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, get_also_info(), get_header(), sip_pvt::initreq, INV_TERMINATED, sip_pvt::invitestate, LOG_DEBUG, LOG_NOTICE, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_pvt::recv, sip_pvt::refer, sip_refer::refer_to, sip_pvt::rtp, sip_alreadygone(), SIP_NO_HISTORY, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_IGNORE, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and sip_pvt::vrtp.
Referenced by handle_request().
15557 { 15558 struct ast_channel *c=NULL; 15559 int res; 15560 struct ast_channel *bridged_to; 15561 15562 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 15563 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 15564 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 15565 15566 __sip_pretend_ack(p); 15567 15568 p->invitestate = INV_TERMINATED; 15569 15570 copy_request(&p->initreq, req); 15571 check_via(p, req); 15572 sip_alreadygone(p); 15573 15574 /* Get RTCP quality before end of call */ 15575 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { 15576 char *audioqos, *videoqos; 15577 if (p->rtp) { 15578 audioqos = ast_rtp_get_quality(p->rtp, NULL); 15579 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 15580 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 15581 if (p->owner) 15582 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 15583 } 15584 if (p->vrtp) { 15585 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 15586 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 15587 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 15588 if (p->owner) 15589 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 15590 } 15591 } 15592 15593 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 15594 15595 if (!ast_strlen_zero(get_header(req, "Also"))) { 15596 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 15597 ast_inet_ntoa(p->recv.sin_addr)); 15598 if (ast_strlen_zero(p->context)) 15599 ast_string_field_set(p, context, default_context); 15600 res = get_also_info(p, req); 15601 if (!res) { 15602 c = p->owner; 15603 if (c) { 15604 bridged_to = ast_bridged_channel(c); 15605 if (bridged_to) { 15606 /* Don't actually hangup here... */ 15607 ast_queue_control(c, AST_CONTROL_UNHOLD); 15608 ast_async_goto(bridged_to, p->context, p->refer->refer_to,1); 15609 } else 15610 ast_queue_hangup(p->owner); 15611 } 15612 } else { 15613 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 15614 if (p->owner) 15615 ast_queue_hangup(p->owner); 15616 } 15617 } else if (p->owner) { 15618 ast_queue_hangup(p->owner); 15619 if (option_debug > 2) 15620 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n"); 15621 } else { 15622 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15623 if (option_debug > 2) 15624 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n"); 15625 } 15626 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15627 transmit_response(p, "200 OK", req); 15628 15629 return 1; 15630 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 15450 of file chan_sip.c.
References __sip_pretend_ack(), ast_log(), ast_queue_hangup(), AST_STATE_UP, ast_test_flag, check_via(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, INV_CANCELLED, INV_TERMINATED, sip_pvt::invitestate, LOG_DEBUG, option_debug, sip_dual::req, sip_alreadygone(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and update_call_counter().
Referenced by handle_request().
15451 { 15452 15453 check_via(p, req); 15454 sip_alreadygone(p); 15455 15456 /* At this point, we could have cancelled the invite at the same time 15457 as the other side sends a CANCEL. Our final reply with error code 15458 might not have been received by the other side before the CANCEL 15459 was sent, so let's just give up retransmissions and waiting for 15460 ACK on our error code. The call is hanging up any way. */ 15461 if (p->invitestate == INV_TERMINATED) 15462 __sip_pretend_ack(p); 15463 else 15464 p->invitestate = INV_CANCELLED; 15465 15466 if (p->owner && p->owner->_state == AST_STATE_UP) { 15467 /* This call is up, cancel is ignored, we need a bye */ 15468 transmit_response(p, "200 OK", req); 15469 if (option_debug) 15470 ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n"); 15471 return 0; 15472 } 15473 15474 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 15475 update_call_counter(p, DEC_CALL_LIMIT); 15476 15477 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 15478 if (p->owner) 15479 ast_queue_hangup(p->owner); 15480 else 15481 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15482 if (p->initreq.len > 0) { 15483 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 15484 transmit_response(p, "200 OK", req); 15485 return 1; 15486 } else { 15487 transmit_response(p, "481 Call Leg Does Not Exist", req); 15488 return 0; 15489 } 15490 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 11565 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().
11566 { 11567 char buf[1024]; 11568 unsigned int event; 11569 const char *c = get_header(req, "Content-Type"); 11570 11571 /* Need to check the media/type */ 11572 if (!strcasecmp(c, "application/dtmf-relay") || 11573 !strcasecmp(c, "application/DTMF") || 11574 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 11575 unsigned int duration = 0; 11576 11577 /* Try getting the "signal=" part */ 11578 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 11579 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 11580 transmit_response(p, "200 OK", req); /* Should return error */ 11581 return; 11582 } else { 11583 ast_copy_string(buf, c, sizeof(buf)); 11584 } 11585 11586 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 11587 duration = atoi(c); 11588 if (!duration) 11589 duration = 100; /* 100 ms */ 11590 11591 if (!p->owner) { /* not a PBX call */ 11592 transmit_response(p, "481 Call leg/transaction does not exist", req); 11593 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11594 return; 11595 } 11596 11597 if (ast_strlen_zero(buf)) { 11598 transmit_response(p, "200 OK", req); 11599 return; 11600 } 11601 11602 if (buf[0] == '*') 11603 event = 10; 11604 else if (buf[0] == '#') 11605 event = 11; 11606 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 11607 event = 12 + buf[0] - 'A'; 11608 else 11609 event = atoi(buf); 11610 if (event == 16) { 11611 /* send a FLASH event */ 11612 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 11613 ast_queue_frame(p->owner, &f); 11614 if (sipdebug) 11615 ast_verbose("* DTMF-relay event received: FLASH\n"); 11616 } else { 11617 /* send a DTMF event */ 11618 struct ast_frame f = { AST_FRAME_DTMF, }; 11619 if (event < 10) { 11620 f.subclass = '0' + event; 11621 } else if (event < 11) { 11622 f.subclass = '*'; 11623 } else if (event < 12) { 11624 f.subclass = '#'; 11625 } else if (event < 16) { 11626 f.subclass = 'A' + (event - 12); 11627 } 11628 f.len = duration; 11629 ast_queue_frame(p->owner, &f); 11630 if (sipdebug) 11631 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 11632 } 11633 transmit_response(p, "200 OK", req); 11634 return; 11635 } else if (!strcasecmp(c, "application/media_control+xml")) { 11636 /* Eh, we'll just assume it's a fast picture update for now */ 11637 if (p->owner) 11638 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 11639 transmit_response(p, "200 OK", req); 11640 return; 11641 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 11642 /* Client code (from SNOM phone) */ 11643 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 11644 if (p->owner && p->owner->cdr) 11645 ast_cdr_setuserfield(p->owner, c); 11646 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 11647 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 11648 transmit_response(p, "200 OK", req); 11649 } else { 11650 transmit_response(p, "403 Unauthorized", req); 11651 } 11652 return; 11653 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 11654 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 11655 transmit_response(p, "200 OK", req); 11656 return; 11657 } 11658 11659 /* Other type of INFO message, not really understood by Asterisk */ 11660 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 11661 11662 /* Nothing in the header is interesting, now check if content-length is 0 */ 11663 if (!strcasecmp(get_header(req, "Content-Length"), "0")) { 11664 transmit_response(p, "200 OK", req); 11665 return; 11666 } /* else ... there issomething in the message body, do something with it if you need to */ 11667 11668 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 11669 transmit_response(p, "415 Unsupported media type", req); 11670 return; 11671 }
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 14442 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_BUSY, AST_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_setdtmf(), ast_rtp_setdtmfcompensate(), ast_set_flag, ast_setstate(), ast_skip_blanks(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), build_route(), ast_channel::call_forward, sip_pvt::callid, sip_pvt::capability, change_hold_state(), check_user(), check_via(), context, sip_pvt::context, copy_request(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, exten, sip_pvt::exten, extract_uri(), FALSE, find_sdp(), sip_pvt::flags, get_destination(), get_header(), get_rdnis(), get_sip_pvt_byid_locked(), handle_invite_replaces(), ast_channel::hangupcause, sip_request::headers, INC_CALL_LIMIT, sip_pvt::initreq, INV_COMPLETED, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::jointcapability, sip_pvt::lastinvite, sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, make_our_tag(), ast_channel::name, option_debug, sip_pvt::owner, parse_ok_contact(), parse_sip_options(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_request::rlPart2, sip_pvt::rtp, S_OR, sip_alreadygone(), sip_cancel_destroy(), SIP_DTMF, SIP_DTMF_RFC2833, sip_handle_t38_reinvite(), SIP_INVITE, sip_new(), SIP_NO_HISTORY, SIP_OPT_REPLACES, SIP_OUTGOING, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PKT_IGNORE, sip_refer_allocate(), sip_scheddestroy(), sip_tech, sip_tech_info, sip_uri_cmp(), sipdebug, sip_pvt::sipoptions, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_PEER_REINVITE, sip_pvt::tag, ast_channel::tech, ast_channel::tech_pvt, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, sip_pvt::udptl, update_call_counter(), sip_pvt::username, XMIT_CRITICAL, XMIT_RELIABLE, and XMIT_UNRELIABLE.
Referenced by handle_request().
14443 { 14444 int res = 1; 14445 int gotdest; 14446 const char *p_replaces; 14447 char *replace_id = NULL; 14448 const char *required; 14449 unsigned int required_profile = 0; 14450 struct ast_channel *c = NULL; /* New channel */ 14451 int reinvite = 0; 14452 14453 /* Find out what they support */ 14454 if (!p->sipoptions) { 14455 const char *supported = get_header(req, "Supported"); 14456 if (!ast_strlen_zero(supported)) 14457 parse_sip_options(p, supported); 14458 } 14459 14460 /* Find out what they require */ 14461 required = get_header(req, "Require"); 14462 if (!ast_strlen_zero(required)) { 14463 required_profile = parse_sip_options(NULL, required); 14464 if (required_profile && required_profile != SIP_OPT_REPLACES) { 14465 /* At this point we only support REPLACES */ 14466 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 14467 ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required); 14468 p->invitestate = INV_COMPLETED; 14469 if (!p->lastinvite) 14470 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14471 return -1; 14472 } 14473 } 14474 14475 /* Check if this is a loop */ 14476 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 14477 /* This is a call to ourself. Send ourselves an error code and stop 14478 processing immediately, as SIP really has no good mechanism for 14479 being able to call yourself */ 14480 /* If pedantic is on, we need to check the tags. If they're different, this is 14481 in fact a forked call through a SIP proxy somewhere. */ 14482 int different; 14483 if (pedanticsipchecking) 14484 different = sip_uri_cmp(p->initreq.rlPart2, req->rlPart2); 14485 else 14486 different = strcmp(p->initreq.rlPart2, req->rlPart2); 14487 if (!different) { 14488 transmit_response(p, "482 Loop Detected", req); 14489 p->invitestate = INV_COMPLETED; 14490 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14491 return 0; 14492 } else { 14493 /* This is a spiral. What we need to do is to just change the outgoing INVITE 14494 * so that it now routes to the new Request URI. Since we created the INVITE ourselves 14495 * that should be all we need to do. 14496 */ 14497 char *uri = ast_strdupa(req->rlPart2); 14498 char *at = strchr(uri, '@'); 14499 char *peerorhost; 14500 if (option_debug > 2) { 14501 ast_log(LOG_DEBUG, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", p->initreq.rlPart2, req->rlPart2); 14502 } 14503 if (at) { 14504 *at = '\0'; 14505 } 14506 /* Parse out "sip:" */ 14507 if ((peerorhost = strchr(uri, ':'))) { 14508 *peerorhost++ = '\0'; 14509 } 14510 ast_string_field_free(p, theirtag); 14511 /* Treat this as if there were a call forward instead... 14512 */ 14513 ast_string_field_set(p->owner, call_forward, peerorhost); 14514 ast_queue_control(p->owner, AST_CONTROL_BUSY); 14515 return 0; 14516 } 14517 } 14518 14519 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) { 14520 /* We already have a pending invite. Sorry. You are on hold. */ 14521 transmit_response_reliable(p, "491 Request Pending", req); 14522 if (option_debug) 14523 ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 14524 /* Don't destroy dialog here */ 14525 return 0; 14526 } 14527 14528 p_replaces = get_header(req, "Replaces"); 14529 if (!ast_strlen_zero(p_replaces)) { 14530 /* We have a replaces header */ 14531 char *ptr; 14532 char *fromtag = NULL; 14533 char *totag = NULL; 14534 char *start, *to; 14535 int error = 0; 14536 14537 if (p->owner) { 14538 if (option_debug > 2) 14539 ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 14540 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 14541 /* Do not destroy existing call */ 14542 return -1; 14543 } 14544 14545 if (sipdebug && option_debug > 2) 14546 ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 14547 /* Create a buffer we can manipulate */ 14548 replace_id = ast_strdupa(p_replaces); 14549 ast_uri_decode(replace_id); 14550 14551 if (!p->refer && !sip_refer_allocate(p)) { 14552 transmit_response_reliable(p, "500 Server Internal Error", req); 14553 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 14554 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14555 p->invitestate = INV_COMPLETED; 14556 return -1; 14557 } 14558 14559 /* Todo: (When we find phones that support this) 14560 if the replaces header contains ";early-only" 14561 we can only replace the call in early 14562 stage, not after it's up. 14563 14564 If it's not in early mode, 486 Busy. 14565 */ 14566 14567 /* Skip leading whitespace */ 14568 replace_id = ast_skip_blanks(replace_id); 14569 14570 start = replace_id; 14571 while ( (ptr = strsep(&start, ";")) ) { 14572 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 14573 if ( (to = strcasestr(ptr, "to-tag=") ) ) 14574 totag = to + 7; /* skip the keyword */ 14575 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 14576 fromtag = to + 9; /* skip the keyword */ 14577 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 14578 } 14579 } 14580 14581 if (sipdebug && option_debug > 3) 14582 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>"); 14583 14584 14585 /* Try to find call that we are replacing 14586 If we have a Replaces header, we need to cancel that call if we succeed with this call 14587 */ 14588 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 14589 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 14590 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req); 14591 error = 1; 14592 } 14593 14594 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 14595 14596 /* The matched call is the call from the transferer to Asterisk . 14597 We want to bridge the bridged part of the call to the 14598 incoming invite, thus taking over the refered call */ 14599 14600 if (p->refer->refer_call == p) { 14601 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 14602 p->refer->refer_call = NULL; 14603 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 14604 error = 1; 14605 } 14606 14607 if (!error && !p->refer->refer_call->owner) { 14608 /* Oops, someting wrong anyway, no owner, no call */ 14609 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 14610 /* Check for better return code */ 14611 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req); 14612 error = 1; 14613 } 14614 14615 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 ) { 14616 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 14617 transmit_response_reliable(p, "603 Declined (Replaces)", req); 14618 error = 1; 14619 } 14620 14621 if (error) { /* Give up this dialog */ 14622 append_history(p, "Xfer", "INVITE/Replace Failed."); 14623 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14624 ast_mutex_unlock(&p->lock); 14625 if (p->refer->refer_call) { 14626 ast_mutex_unlock(&p->refer->refer_call->lock); 14627 if (p->refer->refer_call->owner) { 14628 ast_channel_unlock(p->refer->refer_call->owner); 14629 } 14630 } 14631 p->invitestate = INV_COMPLETED; 14632 return -1; 14633 } 14634 } 14635 14636 14637 /* Check if this is an INVITE that sets up a new dialog or 14638 a re-invite in an existing dialog */ 14639 14640 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14641 int newcall = (p->initreq.headers ? TRUE : FALSE); 14642 14643 if (sip_cancel_destroy(p)) 14644 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 14645 /* This also counts as a pending invite */ 14646 p->pendinginvite = seqno; 14647 check_via(p, req); 14648 14649 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 14650 if (!p->owner) { /* Not a re-invite */ 14651 if (debug) 14652 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 14653 if (newcall) 14654 append_history(p, "Invite", "New call: %s", p->callid); 14655 parse_ok_contact(p, req); 14656 } else { /* Re-invite on existing call */ 14657 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 14658 /* Handle SDP here if we already have an owner */ 14659 if (find_sdp(req)) { 14660 if (process_sdp(p, req)) { 14661 transmit_response_reliable(p, "488 Not acceptable here", req); 14662 if (!p->lastinvite) 14663 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14664 return -1; 14665 } 14666 } else { 14667 p->jointcapability = p->capability; 14668 if (option_debug > 2) 14669 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 14670 /* Some devices signal they want to be put off hold by sending a re-invite 14671 *without* an SDP, which is supposed to mean "Go back to your state" 14672 and since they put os on remote hold, we go back to off hold */ 14673 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 14674 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 14675 /* Activate a re-invite */ 14676 ast_queue_frame(p->owner, &ast_null_frame); 14677 change_hold_state(p, req, FALSE, 0); 14678 } 14679 } 14680 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */ 14681 append_history(p, "ReInv", "Re-invite received"); 14682 } 14683 } else if (debug) 14684 ast_verbose("Ignoring this INVITE request\n"); 14685 14686 14687 if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) { 14688 /* This is a new invite */ 14689 /* Handle authentication if this is our first invite */ 14690 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 14691 if (res == AUTH_CHALLENGE_SENT) { 14692 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 14693 return 0; 14694 } 14695 if (res < 0) { /* Something failed in authentication */ 14696 if (res == AUTH_FAKE_AUTH) { 14697 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 14698 transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE); 14699 } else { 14700 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 14701 transmit_response_reliable(p, "403 Forbidden", req); 14702 } 14703 p->invitestate = INV_COMPLETED; 14704 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14705 ast_string_field_free(p, theirtag); 14706 return 0; 14707 } 14708 14709 /* We have a succesful authentication, process the SDP portion if there is one */ 14710 if (find_sdp(req)) { 14711 if (process_sdp(p, req)) { 14712 /* Unacceptable codecs */ 14713 transmit_response_reliable(p, "488 Not acceptable here", req); 14714 p->invitestate = INV_COMPLETED; 14715 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14716 if (option_debug) 14717 ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); 14718 return -1; 14719 } 14720 } else { /* No SDP in invite, call control session */ 14721 p->jointcapability = p->capability; 14722 if (option_debug > 1) 14723 ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n"); 14724 } 14725 14726 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 14727 /* This seems redundant ... see !p-owner above */ 14728 if (p->owner) 14729 ast_queue_frame(p->owner, &ast_null_frame); 14730 14731 14732 /* Initialize the context if it hasn't been already */ 14733 if (ast_strlen_zero(p->context)) 14734 ast_string_field_set(p, context, default_context); 14735 14736 14737 /* Check number of concurrent calls -vs- incoming limit HERE */ 14738 if (option_debug) 14739 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 14740 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 14741 if (res < 0) { 14742 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 14743 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 14744 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14745 p->invitestate = INV_COMPLETED; 14746 } 14747 return 0; 14748 } 14749 gotdest = get_destination(p, NULL); /* Get destination right away */ 14750 get_rdnis(p, NULL); /* Get redirect information */ 14751 extract_uri(p, req); /* Get the Contact URI */ 14752 build_contact(p); /* Build our contact header */ 14753 14754 if (p->rtp) { 14755 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 14756 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 14757 } 14758 14759 if (!replace_id && gotdest) { /* No matching extension found */ 14760 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 14761 transmit_response_reliable(p, "484 Address Incomplete", req); 14762 else { 14763 char *decoded_exten = ast_strdupa(p->exten); 14764 14765 transmit_response_reliable(p, "404 Not Found", req); 14766 ast_uri_decode(decoded_exten); 14767 ast_log(LOG_NOTICE, "Call from '%s' to extension" 14768 " '%s' rejected because extension not found.\n", 14769 S_OR(p->username, p->peername), decoded_exten); 14770 } 14771 p->invitestate = INV_COMPLETED; 14772 update_call_counter(p, DEC_CALL_LIMIT); 14773 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14774 return 0; 14775 } else { 14776 /* If no extension was specified, use the s one */ 14777 /* Basically for calling to IP/Host name only */ 14778 if (ast_strlen_zero(p->exten)) 14779 ast_string_field_set(p, exten, "s"); 14780 /* Initialize our tag */ 14781 14782 make_our_tag(p->tag, sizeof(p->tag)); 14783 /* First invitation - create the channel */ 14784 c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL)); 14785 *recount = 1; 14786 14787 /* Save Record-Route for any later requests we make on this dialogue */ 14788 build_route(p, req, 0); 14789 14790 if (c) { 14791 /* Pre-lock the call */ 14792 ast_channel_lock(c); 14793 } 14794 } 14795 } else { 14796 if (option_debug > 1 && sipdebug) { 14797 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 14798 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 14799 else 14800 ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 14801 } 14802 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 14803 reinvite = 1; 14804 c = p->owner; 14805 } 14806 14807 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 14808 p->lastinvite = seqno; 14809 14810 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 14811 /* Go and take over the target call */ 14812 if (sipdebug && option_debug > 3) 14813 ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid); 14814 return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin); 14815 } 14816 14817 14818 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 14819 switch(c->_state) { 14820 case AST_STATE_DOWN: 14821 if (option_debug > 1) 14822 ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name); 14823 transmit_response(p, "100 Trying", req); 14824 p->invitestate = INV_PROCEEDING; 14825 ast_setstate(c, AST_STATE_RING); 14826 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 14827 enum ast_pbx_result res; 14828 14829 res = ast_pbx_start(c); 14830 14831 switch(res) { 14832 case AST_PBX_FAILED: 14833 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 14834 p->invitestate = INV_COMPLETED; 14835 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14836 transmit_response(p, "503 Unavailable", req); 14837 else 14838 transmit_response_reliable(p, "503 Unavailable", req); 14839 break; 14840 case AST_PBX_CALL_LIMIT: 14841 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 14842 p->invitestate = INV_COMPLETED; 14843 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14844 transmit_response(p, "480 Temporarily Unavailable", req); 14845 else 14846 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 14847 break; 14848 case AST_PBX_SUCCESS: 14849 /* nothing to do */ 14850 break; 14851 } 14852 14853 if (res) { 14854 14855 /* Unlock locks so ast_hangup can do its magic */ 14856 ast_mutex_unlock(&c->lock); 14857 ast_mutex_unlock(&p->lock); 14858 ast_hangup(c); 14859 ast_mutex_lock(&p->lock); 14860 c = NULL; 14861 } 14862 } else { /* Pickup call in call group */ 14863 ast_channel_unlock(c); 14864 *nounlock = 1; 14865 if (ast_pickup_call(c)) { 14866 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 14867 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14868 transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */ 14869 else 14870 transmit_response_reliable(p, "503 Unavailable", req); 14871 sip_alreadygone(p); 14872 /* Unlock locks so ast_hangup can do its magic */ 14873 ast_mutex_unlock(&p->lock); 14874 c->hangupcause = AST_CAUSE_CALL_REJECTED; 14875 } else { 14876 ast_mutex_unlock(&p->lock); 14877 ast_setstate(c, AST_STATE_DOWN); 14878 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14879 } 14880 p->invitestate = INV_COMPLETED; 14881 ast_hangup(c); 14882 ast_mutex_lock(&p->lock); 14883 c = NULL; 14884 } 14885 break; 14886 case AST_STATE_RING: 14887 transmit_response(p, "100 Trying", req); 14888 p->invitestate = INV_PROCEEDING; 14889 break; 14890 case AST_STATE_RINGING: 14891 transmit_response(p, "180 Ringing", req); 14892 p->invitestate = INV_PROCEEDING; 14893 break; 14894 case AST_STATE_UP: 14895 if (option_debug > 1) 14896 ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); 14897 14898 transmit_response(p, "100 Trying", req); 14899 14900 if (p->t38.state == T38_PEER_REINVITE) { 14901 struct ast_channel *bridgepeer = NULL; 14902 struct sip_pvt *bridgepvt = NULL; 14903 14904 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14905 /* 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*/ 14906 /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */ 14907 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 14908 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14909 if (bridgepvt->t38.state == T38_DISABLED) { 14910 if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */ 14911 /* Send re-invite to the bridged channel */ 14912 sip_handle_t38_reinvite(bridgepeer, p, 1); 14913 } else { /* Something is wrong with peers udptl struct */ 14914 ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n"); 14915 ast_mutex_lock(&bridgepvt->lock); 14916 bridgepvt->t38.state = T38_DISABLED; 14917 ast_mutex_unlock(&bridgepvt->lock); 14918 if (option_debug > 1) 14919 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name); 14920 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14921 transmit_response(p, "488 Not acceptable here", req); 14922 else 14923 transmit_response_reliable(p, "488 Not acceptable here", req); 14924 14925 } 14926 } else { 14927 /* The other side is already setup for T.38 most likely so we need to acknowledge this too */ 14928 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 14929 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14930 p->t38.state = T38_ENABLED; 14931 if (option_debug) 14932 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14933 } 14934 } else { 14935 /* Other side is not a SIP channel */ 14936 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14937 transmit_response(p, "488 Not acceptable here", req); 14938 else 14939 transmit_response_reliable(p, "488 Not acceptable here", req); 14940 p->t38.state = T38_DISABLED; 14941 if (option_debug > 1) 14942 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14943 14944 if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */ 14945 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14946 } 14947 } else { 14948 /* we are not bridged in a call */ 14949 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 14950 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14951 p->t38.state = T38_ENABLED; 14952 if (option_debug) 14953 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14954 } 14955 } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */ 14956 int sendok = TRUE; 14957 14958 /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */ 14959 /* so handle it here (re-invite other party to RTP) */ 14960 struct ast_channel *bridgepeer = NULL; 14961 struct sip_pvt *bridgepvt = NULL; 14962 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14963 if ((bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) && !ast_check_hangup(bridgepeer)) { 14964 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14965 /* Does the bridged peer have T38 ? */ 14966 if (bridgepvt->t38.state == T38_ENABLED) { 14967 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 14968 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 14969 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14970 transmit_response(p, "488 Not Acceptable Here (unsupported)", req); 14971 else 14972 transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req); 14973 sendok = FALSE; 14974 } 14975 /* No bridged peer with T38 enabled*/ 14976 } 14977 } 14978 /* Respond to normal re-invite */ 14979 if (sendok) { 14980 /* If this is not a re-invite or something to ignore - it's critical */ 14981 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 14982 transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_CRITICAL))); 14983 } 14984 } 14985 p->invitestate = INV_TERMINATED; 14986 break; 14987 default: 14988 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 14989 transmit_response(p, "100 Trying", req); 14990 break; 14991 } 14992 } else { 14993 if (p && (p->autokillid == -1)) { 14994 const char *msg; 14995 14996 if (!p->jointcapability) 14997 msg = "488 Not Acceptable Here (codec error)"; 14998 else { 14999 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 15000 msg = "503 Unavailable"; 15001 } 15002 if (ast_test_flag(req, SIP_PKT_IGNORE)) 15003 transmit_response(p, msg, req); 15004 else 15005 transmit_response_reliable(p, msg, req); 15006 p->invitestate = INV_COMPLETED; 15007 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15008 } 15009 } 15010 return res; 15011 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 15633 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().
15634 { 15635 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 15636 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15637 ast_verbose("Receiving message!\n"); 15638 receive_message(p, req); 15639 } else 15640 transmit_response(p, "202 Accepted", req); 15641 return 1; 15642 }
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 13825 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().
13826 { 13827 /* This is mostly a skeleton for future improvements */ 13828 /* Mostly created to return proper answers on notifications on outbound REFER's */ 13829 int res = 0; 13830 const char *event = get_header(req, "Event"); 13831 char *eventid = NULL; 13832 char *sep; 13833 13834 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 13835 *sep++ = '\0'; 13836 eventid = sep; 13837 } 13838 13839 if (option_debug > 1 && sipdebug) 13840 ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event); 13841 13842 if (strcmp(event, "refer")) { 13843 /* We don't understand this event. */ 13844 /* Here's room to implement incoming voicemail notifications :-) */ 13845 transmit_response(p, "489 Bad event", req); 13846 res = -1; 13847 } else { 13848 /* Save nesting depth for now, since there might be other events we will 13849 support in the future */ 13850 13851 /* Handle REFER notifications */ 13852 13853 char buf[1024]; 13854 char *cmd, *code; 13855 int respcode; 13856 int success = TRUE; 13857 13858 /* EventID for each transfer... EventID is basically the REFER cseq 13859 13860 We are getting notifications on a call that we transfered 13861 We should hangup when we are getting a 200 OK in a sipfrag 13862 Check if we have an owner of this event */ 13863 13864 /* Check the content type */ 13865 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 13866 /* We need a sipfrag */ 13867 transmit_response(p, "400 Bad request", req); 13868 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13869 return -1; 13870 } 13871 13872 /* Get the text of the attachment */ 13873 if (get_msg_text(buf, sizeof(buf), req)) { 13874 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 13875 transmit_response(p, "400 Bad request", req); 13876 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13877 return -1; 13878 } 13879 13880 /* 13881 From the RFC... 13882 A minimal, but complete, implementation can respond with a single 13883 NOTIFY containing either the body: 13884 SIP/2.0 100 Trying 13885 13886 if the subscription is pending, the body: 13887 SIP/2.0 200 OK 13888 if the reference was successful, the body: 13889 SIP/2.0 503 Service Unavailable 13890 if the reference failed, or the body: 13891 SIP/2.0 603 Declined 13892 13893 if the REFER request was accepted before approval to follow the 13894 reference could be obtained and that approval was subsequently denied 13895 (see Section 2.4.7). 13896 13897 If there are several REFERs in the same dialog, we need to 13898 match the ID of the event header... 13899 */ 13900 if (option_debug > 2) 13901 ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 13902 cmd = ast_skip_blanks(buf); 13903 code = cmd; 13904 /* We are at SIP/2.0 */ 13905 while(*code && (*code > 32)) { /* Search white space */ 13906 code++; 13907 } 13908 *code++ = '\0'; 13909 code = ast_skip_blanks(code); 13910 sep = code; 13911 sep++; 13912 while(*sep && (*sep > 32)) { /* Search white space */ 13913 sep++; 13914 } 13915 *sep++ = '\0'; /* Response string */ 13916 respcode = atoi(code); 13917 switch (respcode) { 13918 case 100: /* Trying: */ 13919 case 101: /* dialog establishment */ 13920 /* Don't do anything yet */ 13921 break; 13922 case 183: /* Ringing: */ 13923 /* Don't do anything yet */ 13924 break; 13925 case 200: /* OK: The new call is up, hangup this call */ 13926 /* Hangup the call that we are replacing */ 13927 break; 13928 case 301: /* Moved permenantly */ 13929 case 302: /* Moved temporarily */ 13930 /* Do we get the header in the packet in this case? */ 13931 success = FALSE; 13932 break; 13933 case 503: /* Service Unavailable: The new call failed */ 13934 /* Cancel transfer, continue the call */ 13935 success = FALSE; 13936 break; 13937 case 603: /* Declined: Not accepted */ 13938 /* Cancel transfer, continue the current call */ 13939 success = FALSE; 13940 break; 13941 } 13942 if (!success) { 13943 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 13944 } 13945 13946 /* Confirm that we received this packet */ 13947 transmit_response(p, "200 OK", req); 13948 }; 13949 13950 if (!p->lastinvite) 13951 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13952 13953 return res; 13954 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming OPTIONS request.
Definition at line 13957 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().
13958 { 13959 int res; 13960 13961 13962 /* XXX Should we authenticate OPTIONS? XXX */ 13963 13964 if (p->lastinvite) { 13965 /* if this is a request in an active dialog, just confirm that the dialog exists. */ 13966 transmit_response_with_allow(p, "200 OK", req, 0); 13967 return 0; 13968 } 13969 13970 res = get_destination(p, req); 13971 build_contact(p); 13972 13973 if (ast_strlen_zero(p->context)) 13974 ast_string_field_set(p, context, default_context); 13975 13976 if (ast_shutting_down()) 13977 transmit_response_with_allow(p, "503 Unavailable", req, 0); 13978 else if (res < 0) 13979 transmit_response_with_allow(p, "404 Not Found", req, 0); 13980 else 13981 transmit_response_with_allow(p, "200 OK", req, 0); 13982 13983 /* Destroy if this OPTIONS was the opening request, but not if 13984 it's in the middle of a normal call flow. */ 13985 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13986 13987 return res; 13988 }
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 15179 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().
15180 { 15181 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 15182 /* Chan2: Call between asterisk and transferee */ 15183 15184 int res = 0; 15185 15186 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15187 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"); 15188 15189 if (!p->owner) { 15190 /* This is a REFER outside of an existing SIP dialog */ 15191 /* We can't handle that, so decline it */ 15192 if (option_debug > 2) 15193 ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 15194 transmit_response(p, "603 Declined (No dialog)", req); 15195 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 15196 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 15197 sip_alreadygone(p); 15198 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15199 } 15200 return 0; 15201 } 15202 15203 15204 /* Check if transfer is allowed from this device */ 15205 if (p->allowtransfer == TRANSFER_CLOSED ) { 15206 /* Transfer not allowed, decline */ 15207 transmit_response(p, "603 Declined (policy)", req); 15208 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 15209 /* Do not destroy SIP session */ 15210 return 0; 15211 } 15212 15213 if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 15214 /* Already have a pending REFER */ 15215 transmit_response(p, "491 Request pending", req); 15216 append_history(p, "Xfer", "Refer failed. Request pending."); 15217 return 0; 15218 } 15219 15220 /* Allocate memory for call transfer data */ 15221 if (!p->refer && !sip_refer_allocate(p)) { 15222 transmit_response(p, "500 Internal Server Error", req); 15223 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 15224 return -3; 15225 } 15226 15227 res = get_refer_info(p, req); /* Extract headers */ 15228 15229 p->refer->status = REFER_SENT; 15230 15231 if (res != 0) { 15232 switch (res) { 15233 case -2: /* Syntax error */ 15234 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 15235 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 15236 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 15237 ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 15238 break; 15239 case -3: 15240 transmit_response(p, "603 Declined (Non sip: uri)", req); 15241 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 15242 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 15243 ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n"); 15244 break; 15245 default: 15246 /* Refer-to extension not found, fake a failed transfer */ 15247 transmit_response(p, "202 Accepted", req); 15248 append_history(p, "Xfer", "Refer failed. Bad extension."); 15249 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 15250 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15251 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 15252 ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 15253 break; 15254 } 15255 return 0; 15256 } 15257 if (ast_strlen_zero(p->context)) 15258 ast_string_field_set(p, context, default_context); 15259 15260 /* If we do not support SIP domains, all transfers are local */ 15261 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 15262 p->refer->localtransfer = 1; 15263 if (sipdebug && option_debug > 2) 15264 ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 15265 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 15266 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 15267 p->refer->localtransfer = 1; 15268 } else if (sipdebug && option_debug > 2) 15269 ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 15270 15271 /* Is this a repeat of a current request? Ignore it */ 15272 /* Don't know what else to do right now. */ 15273 if (ignore) 15274 return res; 15275 15276 /* If this is a blind transfer, we have the following 15277 channels to work with: 15278 - chan1, chan2: The current call between transferer and transferee (2 channels) 15279 - target_channel: A new call from the transferee to the target (1 channel) 15280 We need to stay tuned to what happens in order to be able 15281 to bring back the call to the transferer */ 15282 15283 /* If this is a attended transfer, we should have all call legs within reach: 15284 - chan1, chan2: The call between the transferer and transferee (2 channels) 15285 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 15286 We want to bridge chan2 with targetcall_pvt! 15287 15288 The replaces call id in the refer message points 15289 to the call leg between Asterisk and the transferer. 15290 So we need to connect the target and the transferee channel 15291 and hangup the two other channels silently 15292 15293 If the target is non-local, the call ID could be on a remote 15294 machine and we need to send an INVITE with replaces to the 15295 target. We basically handle this as a blind transfer 15296 and let the sip_call function catch that we need replaces 15297 header in the INVITE. 15298 */ 15299 15300 15301 /* Get the transferer's channel */ 15302 current.chan1 = p->owner; 15303 15304 /* Find the other part of the bridge (2) - transferee */ 15305 current.chan2 = ast_bridged_channel(current.chan1); 15306 15307 if (sipdebug && option_debug > 2) 15308 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>"); 15309 15310 if (!current.chan2 && !p->refer->attendedtransfer) { 15311 /* No bridged channel, propably IVR or echo or similar... */ 15312 /* Guess we should masquerade or something here */ 15313 /* Until we figure it out, refuse transfer of such calls */ 15314 if (sipdebug && option_debug > 2) 15315 ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n"); 15316 p->refer->status = REFER_FAILED; 15317 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 15318 transmit_response(p, "603 Declined", req); 15319 return -1; 15320 } 15321 15322 if (current.chan2) { 15323 if (sipdebug && option_debug > 3) 15324 ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 15325 15326 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 15327 } 15328 15329 ast_set_flag(&p->flags[0], SIP_GOTREFER); 15330 15331 /* Attended transfer: Find all call legs and bridge transferee with target*/ 15332 if (p->refer->attendedtransfer) { 15333 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 15334 return res; /* We're done with the transfer */ 15335 /* Fall through for remote transfers that we did not find locally */ 15336 if (sipdebug && option_debug > 3) 15337 ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 15338 /* Fallthrough if we can't find the call leg internally */ 15339 } 15340 15341 15342 /* Parking a call */ 15343 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 15344 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 15345 *nounlock = 1; 15346 ast_channel_unlock(current.chan1); 15347 copy_request(¤t.req, req); 15348 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15349 p->refer->status = REFER_200OK; 15350 append_history(p, "Xfer", "REFER to call parking."); 15351 if (sipdebug && option_debug > 3) 15352 ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 15353 sip_park(current.chan2, current.chan1, req, seqno); 15354 return res; 15355 } 15356 15357 /* Blind transfers and remote attended xfers */ 15358 transmit_response(p, "202 Accepted", req); 15359 15360 if (current.chan1 && current.chan2) { 15361 if (option_debug > 2) 15362 ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name); 15363 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 15364 } 15365 if (current.chan2) { 15366 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 15367 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 15368 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 15369 /* One for the new channel */ 15370 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 15371 /* Attended transfer to remote host, prepare headers for the INVITE */ 15372 if (p->refer->referred_by) 15373 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 15374 } 15375 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 15376 if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) { 15377 char tempheader[SIPBUFSIZE]; 15378 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 15379 p->refer->replaces_callid_totag ? ";to-tag=" : "", 15380 p->refer->replaces_callid_totag, 15381 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 15382 p->refer->replaces_callid_fromtag); 15383 if (current.chan2) 15384 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 15385 } 15386 /* Must release lock now, because it will not longer 15387 be accessible after the transfer! */ 15388 *nounlock = 1; 15389 ast_channel_unlock(current.chan1); 15390 15391 /* Connect the call */ 15392 15393 /* FAKE ringing if not attended transfer */ 15394 if (!p->refer->attendedtransfer) 15395 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 15396 15397 /* For blind transfer, this will lead to a new call */ 15398 /* For attended transfer to remote host, this will lead to 15399 a new SIP call with a replaces header, if the dial plan allows it 15400 */ 15401 if (!current.chan2) { 15402 /* We have no bridge, so we're talking with Asterisk somehow */ 15403 /* We need to masquerade this call */ 15404 /* What to do to fix this situation: 15405 * Set up the new call in a new channel 15406 * Let the new channel masq into this channel 15407 Please add that code here :-) 15408 */ 15409 p->refer->status = REFER_FAILED; 15410 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 15411 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15412 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 15413 return -1; 15414 } 15415 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 15416 15417 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 15418 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 15419 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 15420 15421 if (!res) { 15422 /* Success - we have a new channel */ 15423 if (option_debug > 2) 15424 ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 15425 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 15426 if (p->refer->localtransfer) 15427 p->refer->status = REFER_200OK; 15428 if (p->owner) 15429 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 15430 append_history(p, "Xfer", "Refer succeeded."); 15431 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15432 /* Do not hangup call, the other side do that when we say 200 OK */ 15433 /* We could possibly implement a timer here, auto congestion */ 15434 res = 0; 15435 } else { 15436 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 15437 if (option_debug > 2) 15438 ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 15439 append_history(p, "Xfer", "Refer failed."); 15440 /* Failure of some kind */ 15441 p->refer->status = REFER_FAILED; 15442 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 15443 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15444 res = -1; 15445 } 15446 return res; 15447 }
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 15944 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().
15945 { 15946 enum check_auth_result res; 15947 15948 /* Use this as the basis */ 15949 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15950 ast_verbose("Using latest REGISTER request as basis request\n"); 15951 copy_request(&p->initreq, req); 15952 check_via(p, req); 15953 if ((res = register_verify(p, sin, req, e)) < 0) { 15954 const char *reason; 15955 15956 switch (res) { 15957 case AUTH_SECRET_FAILED: 15958 reason = "Wrong password"; 15959 break; 15960 case AUTH_USERNAME_MISMATCH: 15961 reason = "Username/auth name mismatch"; 15962 break; 15963 case AUTH_NOT_FOUND: 15964 reason = "No matching peer found"; 15965 break; 15966 case AUTH_UNKNOWN_DOMAIN: 15967 reason = "Not a local domain"; 15968 break; 15969 case AUTH_PEER_NOT_DYNAMIC: 15970 reason = "Peer is not supposed to register"; 15971 break; 15972 case AUTH_ACL_FAILED: 15973 reason = "Device does not match ACL"; 15974 break; 15975 default: 15976 reason = "Unknown failure"; 15977 break; 15978 } 15979 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 15980 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 15981 reason); 15982 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 15983 } else 15984 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 15985 15986 if (res < 1) { 15987 /* Destroy the session, but keep us around for just a bit in case they don't 15988 get our 200 OK */ 15989 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15990 } 15991 return res; 15992 }
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 15645 of file chan_sip.c.
References append_history, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_extension_state_del(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), sip_pvt::callid, cb_extensionstate(), check_user_full(), check_via(), sip_pvt::context, copy_request(), CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, sip_pvt::expiry, sip_pvt::exten, FALSE, sip_pvt::flags, get_destination(), get_header(), gettag(), sip_request::headers, iflist, iflock, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::laststate, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, sip_peer::mailbox, make_our_tag(), sip_request::method, sip_peer::mwipvt, sip_peer::name, sip_pvt::next, NONE, option_debug, parse_ok_contact(), PIDF_XML, sip_pvt::relatedpeer, sip_pvt::sa, sip_cancel_destroy(), sip_destroy(), sip_destroy_peer(), sip_methods, SIP_NEEDDESTROY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_scheddestroy(), sip_send_mwi_to_peer(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stateid, sip_pvt::subscribecontext, sip_pvt::subscribed, sip_pvt::subscribeuri, sip_pvt::tag, cfsip_methods::text, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_state_notify(), TRUE, sip_pvt::useragent, sip_pvt::username, XMIT_UNRELIABLE, and XPIDF_XML.
Referenced by handle_request().
15646 { 15647 int gotdest = 0; 15648 int res = 0; 15649 int firststate = AST_EXTENSION_REMOVED; 15650 struct sip_peer *authpeer = NULL; 15651 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 15652 const char *accept = get_header(req, "Accept"); 15653 int resubscribe = (p->subscribed != NONE); 15654 char *temp, *event; 15655 15656 if (p->initreq.headers) { 15657 /* We already have a dialog */ 15658 if (p->initreq.method != SIP_SUBSCRIBE) { 15659 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 15660 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 15661 transmit_response(p, "403 Forbidden (within dialog)", req); 15662 /* Do not destroy session, since we will break the call if we do */ 15663 if (option_debug) 15664 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); 15665 return 0; 15666 } else if (ast_test_flag(req, SIP_PKT_DEBUG)) { 15667 if (option_debug) { 15668 if (resubscribe) 15669 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 15670 else 15671 ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid); 15672 } 15673 } 15674 } 15675 15676 /* Check if we have a global disallow setting on subscriptions. 15677 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 15678 */ 15679 if (!global_allowsubscribe) { 15680 transmit_response(p, "403 Forbidden (policy)", req); 15681 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15682 return 0; 15683 } 15684 15685 if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */ 15686 const char *to = get_header(req, "To"); 15687 char totag[128]; 15688 15689 /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */ 15690 if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) { 15691 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15692 ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n"); 15693 transmit_response(p, "481 Subscription does not exist", req); 15694 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15695 return 0; 15696 } 15697 15698 /* Use this as the basis */ 15699 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15700 ast_verbose("Creating new subscription\n"); 15701 15702 copy_request(&p->initreq, req); 15703 check_via(p, req); 15704 } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE)) 15705 ast_verbose("Ignoring this SUBSCRIBE request\n"); 15706 15707 /* Find parameters to Event: header value and remove them for now */ 15708 if (ast_strlen_zero(eventheader)) { 15709 transmit_response(p, "489 Bad Event", req); 15710 if (option_debug > 1) 15711 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n"); 15712 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15713 return 0; 15714 } 15715 15716 if ( (strchr(eventheader, ';'))) { 15717 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 15718 temp = strchr(event, ';'); 15719 *temp = '\0'; /* Remove any options for now */ 15720 /* We might need to use them later :-) */ 15721 } else 15722 event = (char *) eventheader; /* XXX is this legal ? */ 15723 15724 /* Handle authentication */ 15725 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 15726 /* if an authentication response was sent, we are done here */ 15727 if (res == AUTH_CHALLENGE_SENT) { 15728 if (authpeer) 15729 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15730 return 0; 15731 } 15732 if (res < 0) { 15733 if (res == AUTH_FAKE_AUTH) { 15734 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 15735 transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE); 15736 } else { 15737 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 15738 transmit_response_reliable(p, "403 Forbidden", req); 15739 } 15740 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15741 if (authpeer) 15742 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15743 return 0; 15744 } 15745 15746 /* Check if this user/peer is allowed to subscribe at all */ 15747 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 15748 transmit_response(p, "403 Forbidden (policy)", req); 15749 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15750 if (authpeer) 15751 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15752 return 0; 15753 } 15754 15755 if (strcmp(event, "message-summary")) { 15756 /* Get destination right away */ 15757 gotdest = get_destination(p, NULL); 15758 } 15759 15760 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 15761 parse_ok_contact(p, req); 15762 15763 build_contact(p); 15764 if (gotdest) { 15765 transmit_response(p, "404 Not Found", req); 15766 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15767 if (authpeer) 15768 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15769 return 0; 15770 } 15771 15772 /* Initialize tag for new subscriptions */ 15773 if (ast_strlen_zero(p->tag)) 15774 make_our_tag(p->tag, sizeof(p->tag)); 15775 15776 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 15777 if (authpeer) /* No need for authpeer here */ 15778 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15779 15780 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 15781 /* Polycom phones only handle xpidf+xml, even if they say they can 15782 handle pidf+xml as well 15783 */ 15784 if (strstr(p->useragent, "Polycom")) { 15785 p->subscribed = XPIDF_XML; 15786 } else if (strstr(accept, "application/pidf+xml")) { 15787 p->subscribed = PIDF_XML; /* RFC 3863 format */ 15788 } else if (strstr(accept, "application/dialog-info+xml")) { 15789 p->subscribed = DIALOG_INFO_XML; 15790 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 15791 } else if (strstr(accept, "application/cpim-pidf+xml")) { 15792 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 15793 } else if (strstr(accept, "application/xpidf+xml")) { 15794 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 15795 } else if (ast_strlen_zero(accept)) { 15796 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 15797 transmit_response(p, "489 Bad Event", req); 15798 15799 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 15800 p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 15801 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15802 return 0; 15803 } 15804 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 15805 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 15806 } else { 15807 /* Can't find a format for events that we know about */ 15808 char mybuf[200]; 15809 snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept); 15810 transmit_response(p, mybuf, req); 15811 15812 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 15813 accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 15814 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15815 return 0; 15816 } 15817 } else if (!strcmp(event, "message-summary")) { 15818 if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) { 15819 /* Format requested that we do not support */ 15820 transmit_response(p, "406 Not Acceptable", req); 15821 if (option_debug > 1) 15822 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept); 15823 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15824 if (authpeer) /* No need for authpeer here */ 15825 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15826 return 0; 15827 } 15828 /* Looks like they actually want a mailbox status 15829 This version of Asterisk supports mailbox subscriptions 15830 The subscribed URI needs to exist in the dial plan 15831 In most devices, this is configurable to the voicemailmain extension you use 15832 */ 15833 if (!authpeer || ast_strlen_zero(authpeer->mailbox)) { 15834 transmit_response(p, "404 Not found (no mailbox)", req); 15835 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15836 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 15837 if (authpeer) /* No need for authpeer here */ 15838 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15839 return 0; 15840 } 15841 15842 p->subscribed = MWI_NOTIFICATION; 15843 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 15844 /* We only allow one subscription per peer */ 15845 sip_destroy(authpeer->mwipvt); 15846 authpeer->mwipvt = p; /* Link from peer to pvt */ 15847 p->relatedpeer = ASTOBJ_REF(authpeer); /* Link from pvt to peer */ 15848 } else { /* At this point, Asterisk does not understand the specified event */ 15849 transmit_response(p, "489 Bad Event", req); 15850 if (option_debug > 1) 15851 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 15852 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15853 if (authpeer) /* No need for authpeer here */ 15854 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15855 return 0; 15856 } 15857 15858 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) { 15859 if (p->stateid > -1) 15860 ast_extension_state_del(p->stateid, cb_extensionstate); 15861 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 15862 } 15863 15864 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 15865 p->lastinvite = seqno; 15866 if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 15867 p->expiry = atoi(get_header(req, "Expires")); 15868 15869 /* check if the requested expiry-time is within the approved limits from sip.conf */ 15870 if (p->expiry > max_expiry) 15871 p->expiry = max_expiry; 15872 if (p->expiry < min_expiry && p->expiry > 0) 15873 p->expiry = min_expiry; 15874 15875 if (sipdebug || option_debug > 1) { 15876 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 15877 ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox); 15878 else 15879 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 15880 } 15881 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 15882 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15883 if (p->expiry > 0) 15884 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 15885 15886 if (p->subscribed == MWI_NOTIFICATION) { 15887 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15888 transmit_response(p, "200 OK", req); 15889 if (p->relatedpeer) { /* Send first notification */ 15890 ASTOBJ_WRLOCK(p->relatedpeer); 15891 sip_send_mwi_to_peer(p->relatedpeer, TRUE); 15892 ASTOBJ_UNLOCK(p->relatedpeer); 15893 } 15894 } else { 15895 struct sip_pvt *p_old; 15896 15897 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 15898 15899 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)); 15900 transmit_response(p, "404 Not found", req); 15901 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15902 return 0; 15903 } 15904 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15905 transmit_response(p, "200 OK", req); 15906 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 15907 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 15908 /* hide the 'complete' exten/context in the refer_to field for later display */ 15909 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 15910 15911 /* remove any old subscription from this peer for the same exten/context, 15912 as the peer has obviously forgotten about it and it's wasteful to wait 15913 for it to expire and send NOTIFY messages to the peer only to have them 15914 ignored (or generate errors) 15915 */ 15916 ast_mutex_lock(&iflock); 15917 for (p_old = iflist; p_old; p_old = p_old->next) { 15918 if (p_old == p) 15919 continue; 15920 if (p_old->initreq.method != SIP_SUBSCRIBE) 15921 continue; 15922 if (p_old->subscribed == NONE) 15923 continue; 15924 ast_mutex_lock(&p_old->lock); 15925 if (!strcmp(p_old->username, p->username)) { 15926 if (!strcmp(p_old->exten, p->exten) && 15927 !strcmp(p_old->context, p->context)) { 15928 ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY); 15929 ast_mutex_unlock(&p_old->lock); 15930 break; 15931 } 15932 } 15933 ast_mutex_unlock(&p_old->lock); 15934 } 15935 ast_mutex_unlock(&iflock); 15936 } 15937 if (!p->expiry) 15938 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15939 } 15940 return 1; 15941 }
static void handle_response | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | ignore, | |||
int | seqno | |||
) | [static] |
Handle SIP response in dialogue.
Definition at line 13105 of file chan_sip.c.
References __sip_ack(), __sip_semi_ack(), ast_clear_flag, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_set_flag, ast_skip_blanks(), ast_skip_nonblanks(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ast_channel::call_forward, cb_extensionstate(), sip_pvt::context, do_proxy_auth(), sip_pvt::exten, FALSE, find_sdp(), find_sip_method(), sip_pvt::flags, get_header(), gettag(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), hangup_sip2cause(), ast_channel::hangupcause, sip_pvt::laststate, LOG_DEBUG, LOG_NOTICE, MAX_AUTHTRIES, sip_pvt::method, NONE, option_debug, option_verbose, sip_pvt::owner, parse_moved_contact(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_pvt::relatedpeer, SIP_ACK, sip_alreadygone(), SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_STATECHANGEQUEUE, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_REFER, SIP_REGISTER, SIP_SUBSCRIBE, sipdebug, stop_media_flows(), sip_pvt::subscribed, text, sip_pvt::theirtag, transmit_request(), VERBOSE_PREFIX_3, and XMIT_UNRELIABLE.
13106 { 13107 struct ast_channel *owner; 13108 int sipmethod; 13109 int res = 1; 13110 const char *c = get_header(req, "Cseq"); 13111 /* 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 */ 13112 char *c_copy = ast_strdupa(c); 13113 /* Skip the Cseq and its subsequent spaces */ 13114 const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy)); 13115 13116 if (!msg) 13117 msg = ""; 13118 13119 sipmethod = find_sip_method(msg); 13120 13121 owner = p->owner; 13122 if (owner) 13123 owner->hangupcause = hangup_sip2cause(resp); 13124 13125 /* Acknowledge whatever it is destined for */ 13126 if ((resp >= 100) && (resp <= 199)) 13127 __sip_semi_ack(p, seqno, 0, sipmethod); 13128 else 13129 __sip_ack(p, seqno, 0, sipmethod); 13130 13131 /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */ 13132 if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 13133 p->pendinginvite = 0; 13134 13135 /* Get their tag if we haven't already */ 13136 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 13137 char tag[128]; 13138 13139 gettag(req, "To", tag, sizeof(tag)); 13140 ast_string_field_set(p, theirtag, tag); 13141 } 13142 13143 /* RFC 3261 Section 15 specifies that if we receive a 408 or 481 13144 * in response to a BYE, then we should end the current dialog 13145 * and session. It is known that at least one phone manufacturer 13146 * potentially will send a 404 in response to a BYE, so we'll be 13147 * liberal in what we accept and end the dialog and session if we 13148 * receive any of those responses to a BYE. 13149 */ 13150 if ((resp == 404 || resp == 408 || resp == 481) && sipmethod == SIP_BYE) { 13151 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13152 return; 13153 } 13154 13155 if (p->relatedpeer && p->method == SIP_OPTIONS) { 13156 /* We don't really care what the response is, just that it replied back. 13157 Well, as long as it's not a 100 response... since we might 13158 need to hang around for something more "definitive" */ 13159 if (resp != 100) 13160 handle_response_peerpoke(p, resp, req); 13161 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 13162 switch(resp) { 13163 case 100: /* 100 Trying */ 13164 case 101: /* 101 Dialog establishment */ 13165 if (sipmethod == SIP_INVITE) 13166 handle_response_invite(p, resp, rest, req, seqno); 13167 break; 13168 case 183: /* 183 Session Progress */ 13169 if (sipmethod == SIP_INVITE) 13170 handle_response_invite(p, resp, rest, req, seqno); 13171 break; 13172 case 180: /* 180 Ringing */ 13173 if (sipmethod == SIP_INVITE) 13174 handle_response_invite(p, resp, rest, req, seqno); 13175 break; 13176 case 182: /* 182 Queued */ 13177 if (sipmethod == SIP_INVITE) 13178 handle_response_invite(p, resp, rest, req, seqno); 13179 break; 13180 case 200: /* 200 OK */ 13181 p->authtries = 0; /* Reset authentication counter */ 13182 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 13183 /* We successfully transmitted a message 13184 or a video update request in INFO */ 13185 /* Nothing happens here - the message is inside a dialog */ 13186 } else if (sipmethod == SIP_INVITE) { 13187 handle_response_invite(p, resp, rest, req, seqno); 13188 } else if (sipmethod == SIP_NOTIFY) { 13189 /* They got the notify, this is the end */ 13190 if (p->owner) { 13191 if (!p->refer) { 13192 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 13193 ast_queue_hangup(p->owner); 13194 } else if (option_debug > 3) 13195 ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n"); 13196 } else { 13197 if (p->subscribed == NONE) 13198 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13199 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 13200 /* Ready to send the next state we have on queue */ 13201 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 13202 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 13203 } 13204 } 13205 } else if (sipmethod == SIP_REGISTER) 13206 res = handle_response_register(p, resp, rest, req, ignore, seqno); 13207 else if (sipmethod == SIP_BYE) { /* Ok, we're ready to go */ 13208 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13209 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 13210 } else if (sipmethod == SIP_SUBSCRIBE) 13211 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 13212 break; 13213 case 202: /* Transfer accepted */ 13214 if (sipmethod == SIP_REFER) 13215 handle_response_refer(p, resp, rest, req, seqno); 13216 break; 13217 case 401: /* Not www-authorized on SIP method */ 13218 if (sipmethod == SIP_INVITE) 13219 handle_response_invite(p, resp, rest, req, seqno); 13220 else if (sipmethod == SIP_REFER) 13221 handle_response_refer(p, resp, rest, req, seqno); 13222 else if (p->registry && sipmethod == SIP_REGISTER) 13223 res = handle_response_register(p, resp, rest, req, ignore, seqno); 13224 else if (sipmethod == SIP_BYE) { 13225 if (ast_strlen_zero(p->authname)) { 13226 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 13227 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 13228 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13229 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) { 13230 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13231 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13232 /* We fail to auth bye on our own call, but still needs to tear down the call. 13233 Life, they call it. */ 13234 } 13235 } else { 13236 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 13237 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13238 } 13239 break; 13240 case 403: /* Forbidden - we failed authentication */ 13241 if (sipmethod == SIP_INVITE) 13242 handle_response_invite(p, resp, rest, req, seqno); 13243 else if (p->registry && sipmethod == SIP_REGISTER) 13244 res = handle_response_register(p, resp, rest, req, ignore, seqno); 13245 else { 13246 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 13247 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13248 } 13249 break; 13250 case 404: /* Not found */ 13251 if (p->registry && sipmethod == SIP_REGISTER) 13252 res = handle_response_register(p, resp, rest, req, ignore, seqno); 13253 else if (sipmethod == SIP_INVITE) 13254 handle_response_invite(p, resp, rest, req, seqno); 13255 else if (owner) 13256 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13257 break; 13258 case 407: /* Proxy auth required */ 13259 if (sipmethod == SIP_INVITE) 13260 handle_response_invite(p, resp, rest, req, seqno); 13261 else if (sipmethod == SIP_REFER) 13262 handle_response_refer(p, resp, rest, req, seqno); 13263 else if (p->registry && sipmethod == SIP_REGISTER) 13264 res = handle_response_register(p, resp, rest, req, ignore, seqno); 13265 else if (sipmethod == SIP_BYE) { 13266 if (ast_strlen_zero(p->authname)) { 13267 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 13268 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 13269 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13270 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 13271 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13272 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13273 } 13274 } else /* We can't handle this, giving up in a bad way */ 13275 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13276 13277 break; 13278 case 408: /* Request timeout - terminate dialog */ 13279 if (sipmethod == SIP_INVITE) 13280 handle_response_invite(p, resp, rest, req, seqno); 13281 else if (sipmethod == SIP_REGISTER) 13282 res = handle_response_register(p, resp, rest, req, ignore, seqno); 13283 else if (sipmethod == SIP_BYE) { 13284 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13285 if (option_debug) 13286 ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 13287 } else { 13288 if (owner) 13289 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13290 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13291 } 13292 break; 13293 case 481: /* Call leg does not exist */ 13294 if (sipmethod == SIP_INVITE) { 13295 handle_response_invite(p, resp, rest, req, seqno); 13296 } else if (sipmethod == SIP_REFER) { 13297 handle_response_refer(p, resp, rest, req, seqno); 13298 } else if (sipmethod == SIP_BYE) { 13299 /* The other side has no transaction to bye, 13300 just assume it's all right then */ 13301 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13302 } else if (sipmethod == SIP_CANCEL) { 13303 /* The other side has no transaction to cancel, 13304 just assume it's all right then */ 13305 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13306 } else { 13307 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13308 /* Guessing that this is not an important request */ 13309 } 13310 break; 13311 case 487: 13312 if (sipmethod == SIP_INVITE) 13313 handle_response_invite(p, resp, rest, req, seqno); 13314 break; 13315 case 488: /* Not acceptable here - codec error */ 13316 if (sipmethod == SIP_INVITE) 13317 handle_response_invite(p, resp, rest, req, seqno); 13318 break; 13319 case 491: /* Pending */ 13320 if (sipmethod == SIP_INVITE) 13321 handle_response_invite(p, resp, rest, req, seqno); 13322 else { 13323 if (option_debug) 13324 ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 13325 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13326 } 13327 break; 13328 case 501: /* Not Implemented */ 13329 if (sipmethod == SIP_INVITE) 13330 handle_response_invite(p, resp, rest, req, seqno); 13331 else if (sipmethod == SIP_REFER) 13332 handle_response_refer(p, resp, rest, req, seqno); 13333 else 13334 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg); 13335 break; 13336 case 603: /* Declined transfer */ 13337 if (sipmethod == SIP_REFER) { 13338 handle_response_refer(p, resp, rest, req, seqno); 13339 break; 13340 } 13341 /* Fallthrough */ 13342 default: 13343 if ((resp >= 300) && (resp < 700)) { 13344 /* Fatal response */ 13345 if ((option_verbose > 2) && (resp != 487)) 13346 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 13347 13348 if (sipmethod == SIP_INVITE) 13349 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 13350 13351 /* XXX Locking issues?? XXX */ 13352 switch(resp) { 13353 case 300: /* Multiple Choices */ 13354 case 301: /* Moved permenantly */ 13355 case 302: /* Moved temporarily */ 13356 case 305: /* Use Proxy */ 13357 parse_moved_contact(p, req); 13358 /* Fall through */ 13359 case 486: /* Busy here */ 13360 case 600: /* Busy everywhere */ 13361 case 603: /* Decline */ 13362 if (p->owner) 13363 ast_queue_control(p->owner, AST_CONTROL_BUSY); 13364 break; 13365 case 482: /* 13366 \note SIP is incapable of performing a hairpin call, which 13367 is yet another failure of not having a layer 2 (again, YAY 13368 IETF for thinking ahead). So we treat this as a call 13369 forward and hope we end up at the right place... */ 13370 if (option_debug) 13371 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 13372 if (p->owner) 13373 ast_string_field_build(p->owner, call_forward, 13374 "Local/%s@%s", p->username, p->context); 13375 /* Fall through */ 13376 case 480: /* Temporarily Unavailable */ 13377 case 404: /* Not Found */ 13378 case 410: /* Gone */ 13379 case 400: /* Bad Request */ 13380 case 500: /* Server error */ 13381 if (sipmethod == SIP_REFER) { 13382 handle_response_refer(p, resp, rest, req, seqno); 13383 break; 13384 } 13385 /* Fall through */ 13386 case 502: /* Bad gateway */ 13387 case 503: /* Service Unavailable */ 13388 case 504: /* Server Timeout */ 13389 if (owner) 13390 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13391 break; 13392 default: 13393 /* Send hangup */ 13394 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE) 13395 ast_queue_hangup(p->owner); 13396 break; 13397 } 13398 /* ACK on invite */ 13399 if (sipmethod == SIP_INVITE) 13400 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13401 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 13402 sip_alreadygone(p); 13403 if (!p->owner) 13404 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13405 } else if ((resp >= 100) && (resp < 200)) { 13406 if (sipmethod == SIP_INVITE) { 13407 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13408 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13409 if (find_sdp(req)) 13410 process_sdp(p, req); 13411 if (p->owner) { 13412 /* Queue a progress frame */ 13413 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 13414 } 13415 } 13416 } else 13417 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)); 13418 } 13419 } else { 13420 /* Responses to OUTGOING SIP requests on INCOMING calls 13421 get handled here. As well as out-of-call message responses */ 13422 if (ast_test_flag(req, SIP_PKT_DEBUG)) 13423 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 13424 13425 if (sipmethod == SIP_INVITE && resp == 200) { 13426 /* Tags in early session is replaced by the tag in 200 OK, which is 13427 the final reply to our INVITE */ 13428 char tag[128]; 13429 13430 gettag(req, "To", tag, sizeof(tag)); 13431 ast_string_field_set(p, theirtag, tag); 13432 } 13433 13434 switch(resp) { 13435 case 200: 13436 if (sipmethod == SIP_INVITE) { 13437 handle_response_invite(p, resp, rest, req, seqno); 13438 } else if (sipmethod == SIP_CANCEL) { 13439 if (option_debug) 13440 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 13441 13442 /* Wait for 487, then destroy */ 13443 } else if (sipmethod == SIP_NOTIFY) { 13444 /* They got the notify, this is the end */ 13445 if (p->owner) { 13446 if (p->refer) { 13447 if (option_debug) 13448 ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n"); 13449 } else 13450 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 13451 /* ast_queue_hangup(p->owner); Disabled */ 13452 } else { 13453 if (!p->subscribed && !p->refer) 13454 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13455 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 13456 /* Ready to send the next state we have on queue */ 13457 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 13458 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 13459 } 13460 } 13461 } else if (sipmethod == SIP_BYE) 13462 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13463 else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) 13464 /* We successfully transmitted a message or 13465 a video update request in INFO */ 13466 ; 13467 else if (sipmethod == SIP_BYE) 13468 /* Ok, we're ready to go */ 13469 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13470 break; 13471 case 202: /* Transfer accepted */ 13472 if (sipmethod == SIP_REFER) 13473 handle_response_refer(p, resp, rest, req, seqno); 13474 break; 13475 case 401: /* www-auth */ 13476 case 407: 13477 if (sipmethod == SIP_REFER) 13478 handle_response_refer(p, resp, rest, req, seqno); 13479 else if (sipmethod == SIP_INVITE) 13480 handle_response_invite(p, resp, rest, req, seqno); 13481 else if (sipmethod == SIP_BYE) { 13482 char *auth, *auth2; 13483 13484 auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate"); 13485 auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization"); 13486 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 13487 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13488 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13489 } 13490 } 13491 break; 13492 case 481: /* Call leg does not exist */ 13493 if (sipmethod == SIP_INVITE) { 13494 /* Re-invite failed */ 13495 handle_response_invite(p, resp, rest, req, seqno); 13496 } else if (sipmethod == SIP_BYE) { 13497 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13498 } else if (sipdebug) { 13499 ast_log (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 13500 } 13501 break; 13502 case 501: /* Not Implemented */ 13503 if (sipmethod == SIP_INVITE) 13504 handle_response_invite(p, resp, rest, req, seqno); 13505 else if (sipmethod == SIP_REFER) 13506 handle_response_refer(p, resp, rest, req, seqno); 13507 break; 13508 case 603: /* Declined transfer */ 13509 if (sipmethod == SIP_REFER) { 13510 handle_response_refer(p, resp, rest, req, seqno); 13511 break; 13512 } 13513 /* Fallthrough */ 13514 default: /* Errors without handlers */ 13515 if ((resp >= 100) && (resp < 200)) { 13516 if (sipmethod == SIP_INVITE) { /* re-invite */ 13517 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13518 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13519 } 13520 } 13521 if ((resp >= 300) && (resp < 700)) { 13522 if ((option_verbose > 2) && (resp != 487)) 13523 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)); 13524 switch(resp) { 13525 case 488: /* Not acceptable here - codec error */ 13526 case 603: /* Decline */ 13527 case 500: /* Server error */ 13528 case 502: /* Bad gateway */ 13529 case 503: /* Service Unavailable */ 13530 case 504: /* Server timeout */ 13531 13532 /* re-invite failed */ 13533 if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) 13534 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13535 break; 13536 } 13537 } 13538 break; 13539 } 13540 } 13541 }
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 12513 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, ast_queue_control(), ast_queue_frame(), ast_queue_hangup(), ast_random(), ast_rtp_set_rtptimers_onhold(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_string_field_free, ast_test_flag, sip_invite_param::auth_type, authenticate(), sip_pvt::authtries, build_route(), sip_pvt::callid, check_pendings(), DEC_CALL_LIMIT, DEC_CALL_RINGING, DEFAULT_TRANS_TIMEOUT, do_proxy_auth(), FALSE, find_sdp(), sip_pvt::flags, get_header(), sip_pvt::initid, sip_pvt::initreq, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, MAX_AUTHTRIES, ast_channel::name, option_debug, sip_pvt::options, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, sip_pvt::rtp, sched, set_address_from_contact(), SIP_ACK, sip_alreadygone(), SIP_ALREADYGONE, sip_cancel_destroy(), sip_handle_t38_reinvite(), SIP_INVITE, SIP_NEEDDESTROY, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PENDINGBYE, SIP_PKT_IGNORE, sip_reinvite_retry(), sip_scheddestroy(), sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, T38_PEER_REINVITE, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::theirtag, transmit_request(), TRUE, ast_channel_tech::type, sip_pvt::udptl, update_call_counter(), sip_pvt::vrtp, sip_pvt::waitid, WWW_AUTH, XMIT_ERROR, and XMIT_UNRELIABLE.
Referenced by handle_response().
12514 { 12515 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 12516 int res = 0; 12517 int xmitres = 0; 12518 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 12519 struct ast_channel *bridgepeer = NULL; 12520 12521 if (option_debug > 3) { 12522 if (reinvite) 12523 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 12524 else 12525 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 12526 } 12527 12528 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */ 12529 if (option_debug) 12530 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 12531 return; 12532 } 12533 12534 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 12535 /* Don't auto congest anymore since we've gotten something useful back */ 12536 AST_SCHED_DEL(sched, p->initid); 12537 12538 /* RFC3261 says we must treat every 1xx response (but not 100) 12539 that we don't recognize as if it was 183. 12540 */ 12541 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183) 12542 resp = 183; 12543 12544 /* Any response between 100 and 199 is PROCEEDING */ 12545 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 12546 p->invitestate = INV_PROCEEDING; 12547 12548 /* Final response, not 200 ? */ 12549 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 12550 p->invitestate = INV_COMPLETED; 12551 12552 12553 switch (resp) { 12554 case 100: /* Trying */ 12555 case 101: /* Dialog establishment */ 12556 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12557 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12558 check_pendings(p); 12559 break; 12560 12561 case 180: /* 180 Ringing */ 12562 case 182: /* 182 Queued */ 12563 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12564 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12565 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12566 ast_queue_control(p->owner, AST_CONTROL_RINGING); 12567 if (p->owner->_state != AST_STATE_UP) { 12568 ast_setstate(p->owner, AST_STATE_RINGING); 12569 } 12570 } 12571 if (find_sdp(req)) { 12572 if (p->invitestate != INV_CANCELLED) 12573 p->invitestate = INV_EARLY_MEDIA; 12574 res = process_sdp(p, req); 12575 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12576 /* Queue a progress frame only if we have SDP in 180 or 182 */ 12577 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12578 } 12579 } 12580 check_pendings(p); 12581 break; 12582 12583 case 183: /* Session progress */ 12584 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12585 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12586 /* Ignore 183 Session progress without SDP */ 12587 if (find_sdp(req)) { 12588 if (p->invitestate != INV_CANCELLED) 12589 p->invitestate = INV_EARLY_MEDIA; 12590 res = process_sdp(p, req); 12591 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12592 /* Queue a progress frame */ 12593 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12594 } 12595 } 12596 check_pendings(p); 12597 break; 12598 12599 case 200: /* 200 OK on invite - someone's answering our call */ 12600 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12601 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12602 p->authtries = 0; 12603 if (find_sdp(req)) { 12604 if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) 12605 if (!reinvite) 12606 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 12607 /* For re-invites, we try to recover */ 12608 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12609 } 12610 12611 /* Parse contact header for continued conversation */ 12612 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 12613 /* This is important when we have a SIP proxy between us and the phone */ 12614 if (outgoing) { 12615 update_call_counter(p, DEC_CALL_RINGING); 12616 parse_ok_contact(p, req); 12617 /* Save Record-Route for any later requests we make on this dialogue */ 12618 if (!reinvite) 12619 build_route(p, req, 1); 12620 12621 if(set_address_from_contact(p)) { 12622 /* Bad contact - we don't know how to reach this device */ 12623 /* We need to ACK, but then send a bye */ 12624 if (!p->route && !ast_test_flag(req, SIP_PKT_IGNORE)) 12625 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12626 } 12627 12628 } 12629 12630 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 12631 struct sip_pvt *bridgepvt = NULL; 12632 12633 if (!bridgepeer->tech) { 12634 ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n"); 12635 break; 12636 } 12637 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 12638 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 12639 if (bridgepvt->udptl) { 12640 if (p->t38.state == T38_PEER_REINVITE) { 12641 sip_handle_t38_reinvite(bridgepeer, p, 0); 12642 ast_rtp_set_rtptimers_onhold(p->rtp); 12643 if (p->vrtp) 12644 ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */ 12645 } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) { 12646 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 12647 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 12648 /* XXXX Should we really destroy this session here, without any response at all??? */ 12649 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12650 } 12651 } else { 12652 if (option_debug > 1) 12653 ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n"); 12654 ast_mutex_lock(&bridgepvt->lock); 12655 bridgepvt->t38.state = T38_DISABLED; 12656 ast_mutex_unlock(&bridgepvt->lock); 12657 if (option_debug) 12658 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type); 12659 p->t38.state = T38_DISABLED; 12660 if (option_debug > 1) 12661 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12662 } 12663 } else { 12664 /* Other side is not a SIP channel */ 12665 if (option_debug > 1) 12666 ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n"); 12667 p->t38.state = T38_DISABLED; 12668 if (option_debug > 1) 12669 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12670 } 12671 } 12672 if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) { 12673 /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */ 12674 p->t38.state = T38_ENABLED; 12675 if (option_debug) 12676 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12677 } 12678 12679 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12680 if (!reinvite) { 12681 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 12682 } else { /* RE-invite */ 12683 ast_queue_frame(p->owner, &ast_null_frame); 12684 } 12685 } else { 12686 /* It's possible we're getting an 200 OK after we've tried to disconnect 12687 by sending CANCEL */ 12688 /* First send ACK, then send bye */ 12689 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12690 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12691 } 12692 /* If I understand this right, the branch is different for a non-200 ACK only */ 12693 p->invitestate = INV_TERMINATED; 12694 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 12695 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 12696 check_pendings(p); 12697 break; 12698 case 407: /* Proxy authentication */ 12699 case 401: /* Www auth */ 12700 /* First we ACK */ 12701 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12702 if (p->options) 12703 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 12704 12705 /* Then we AUTH */ 12706 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 12707 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12708 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 12709 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 12710 if (p->authtries < MAX_AUTHTRIES) 12711 p->invitestate = INV_CALLING; 12712 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 12713 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 12714 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12715 sip_alreadygone(p); 12716 if (p->owner) 12717 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12718 } 12719 } 12720 break; 12721 12722 case 403: /* Forbidden */ 12723 /* First we ACK */ 12724 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12725 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 12726 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) 12727 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12728 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12729 sip_alreadygone(p); 12730 break; 12731 12732 case 404: /* Not found */ 12733 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12734 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12735 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12736 sip_alreadygone(p); 12737 break; 12738 12739 case 408: /* Request timeout */ 12740 case 481: /* Call leg does not exist */ 12741 /* Could be REFER caused INVITE with replaces */ 12742 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 12743 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12744 if (p->owner) 12745 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12746 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12747 break; 12748 case 487: /* Cancelled transaction */ 12749 /* We have sent CANCEL on an outbound INVITE 12750 This transaction is already scheduled to be killed by sip_hangup(). 12751 */ 12752 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12753 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12754 ast_queue_hangup(p->owner); 12755 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 12756 } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12757 update_call_counter(p, DEC_CALL_LIMIT); 12758 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 12759 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12760 sip_alreadygone(p); 12761 } 12762 break; 12763 case 488: /* Not acceptable here */ 12764 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12765 if (reinvite && p->udptl) { 12766 /* If this is a T.38 call, we should go back to 12767 audio. If this is an audio call - something went 12768 terribly wrong since we don't renegotiate codecs, 12769 only IP/port . 12770 */ 12771 p->t38.state = T38_DISABLED; 12772 /* Try to reset RTP timers */ 12773 ast_rtp_set_rtptimers_onhold(p->rtp); 12774 ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n"); 12775 12776 /*! \bug Is there any way we can go back to the audio call on both 12777 sides here? 12778 */ 12779 /* While figuring that out, hangup the call */ 12780 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12781 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12782 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12783 } else if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) { 12784 /* We tried to send T.38 out in an initial INVITE and the remote side rejected it, 12785 right now we can't fall back to audio so totally abort. 12786 */ 12787 p->t38.state = T38_DISABLED; 12788 /* Try to reset RTP timers */ 12789 ast_rtp_set_rtptimers_onhold(p->rtp); 12790 ast_log(LOG_ERROR, "Got error on T.38 initial invite. Bailing out.\n"); 12791 12792 /* The dialog is now terminated */ 12793 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12794 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12795 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12796 sip_alreadygone(p); 12797 } else { 12798 /* We can't set up this call, so give up */ 12799 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12800 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12801 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12802 /* If there's no dialog to end, then mark p as already gone */ 12803 if (!reinvite) 12804 sip_alreadygone(p); 12805 } 12806 break; 12807 case 491: /* Pending */ 12808 /* we really should have to wait a while, then retransmit 12809 * We should support the retry-after at some point 12810 * At this point, we treat this as a congestion if the call is not in UP state 12811 */ 12812 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12813 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12814 if (p->owner->_state != AST_STATE_UP) { 12815 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12816 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12817 } else { 12818 /* This is a re-invite that failed. 12819 * Reset the flag after a while 12820 */ 12821 int wait = 3 + ast_random() % 5; 12822 p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p); 12823 if (option_debug > 2) 12824 ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait); 12825 } 12826 } 12827 break; 12828 12829 case 501: /* Not implemented */ 12830 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12831 if (p->owner) 12832 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12833 break; 12834 } 12835 if (xmitres == XMIT_ERROR) 12836 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 12837 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 13035 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_tvdiff_ms(), ast_tvnow(), ast_update_realtime(), ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::call, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, EVENT_FLAG_SYSTEM, sip_pvt::flags, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::maxms, sip_peer::name, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::relatedpeer, s, sched, sip_destroy_peer(), SIP_NEEDDESTROY, and sip_poke_peer_s().
Referenced by handle_response().
13036 { 13037 struct sip_peer *peer = p->relatedpeer; 13038 int statechanged, is_reachable, was_reachable; 13039 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 13040 13041 /* 13042 * Compute the response time to a ping (goes in peer->lastms.) 13043 * -1 means did not respond, 0 means unknown, 13044 * 1..maxms is a valid response, >maxms means late response. 13045 */ 13046 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 13047 pingtime = 1; 13048 13049 /* Now determine new state and whether it has changed. 13050 * Use some helper variables to simplify the writing 13051 * of the expressions. 13052 */ 13053 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 13054 is_reachable = pingtime <= peer->maxms; 13055 statechanged = peer->lastms == 0 /* yes, unknown before */ 13056 || was_reachable != is_reachable; 13057 13058 peer->lastms = pingtime; 13059 peer->call = NULL; 13060 if (statechanged) { 13061 const char *s = is_reachable ? "Reachable" : "Lagged"; 13062 char str_lastms[20]; 13063 snprintf(str_lastms, sizeof(str_lastms), "%d", pingtime); 13064 13065 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 13066 peer->name, s, pingtime, peer->maxms); 13067 ast_device_state_changed("SIP/%s", peer->name); 13068 ast_update_realtime("sippeers", "name", peer->name, "lastms", str_lastms, NULL); 13069 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 13070 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 13071 peer->name, s, pingtime); 13072 } 13073 13074 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 13075 struct sip_peer *peer_ptr = peer; 13076 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 13077 } 13078 13079 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13080 13081 /* Try again eventually */ 13082 peer->pokeexpire = ast_sched_add(sched, 13083 is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, 13084 sip_poke_peer_s, ASTOBJ_REF(peer)); 13085 13086 if (peer->pokeexpire == -1) { 13087 ASTOBJ_UNREF(peer, sip_destroy_peer); 13088 } 13089 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 12842 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().
12843 { 12844 char *auth = "Proxy-Authenticate"; 12845 char *auth2 = "Proxy-Authorization"; 12846 12847 /* If no refer structure exists, then do nothing */ 12848 if (!p->refer) 12849 return; 12850 12851 switch (resp) { 12852 case 202: /* Transfer accepted */ 12853 /* We need to do something here */ 12854 /* The transferee is now sending INVITE to target */ 12855 p->refer->status = REFER_ACCEPTED; 12856 /* Now wait for next message */ 12857 if (option_debug > 2) 12858 ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n"); 12859 /* We should hang along, waiting for NOTIFY's here */ 12860 break; 12861 12862 case 401: /* Not www-authorized on SIP method */ 12863 case 407: /* Proxy auth */ 12864 if (ast_strlen_zero(p->authname)) { 12865 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 12866 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12867 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12868 } 12869 if (resp == 401) { 12870 auth = "WWW-Authenticate"; 12871 auth2 = "Authorization"; 12872 } 12873 if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) { 12874 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 12875 p->refer->status = REFER_NOAUTH; 12876 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12877 } 12878 break; 12879 case 481: /* Call leg does not exist */ 12880 12881 /* A transfer with Replaces did not work */ 12882 /* OEJ: We should Set flag, cancel the REFER, go back 12883 to original call - but right now we can't */ 12884 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 12885 if (p->owner) 12886 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12887 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12888 break; 12889 12890 case 500: /* Server error */ 12891 case 501: /* Method not implemented */ 12892 /* Return to the current call onhold */ 12893 /* Status flag needed to be reset */ 12894 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 12895 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12896 p->refer->status = REFER_FAILED; 12897 break; 12898 case 603: /* Transfer declined */ 12899 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 12900 p->refer->status = REFER_FAILED; 12901 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12902 break; 12903 } 12904 }
static int handle_response_register | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | ignore, | |||
int | seqno | |||
) | [static] |
Handle responses on REGISTER to services.
Definition at line 12907 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().
12908 { 12909 int expires, expires_ms; 12910 struct sip_registry *r; 12911 r=p->registry; 12912 12913 switch (resp) { 12914 case 401: /* Unauthorized */ 12915 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 12916 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 12917 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12918 } 12919 break; 12920 case 403: /* Forbidden */ 12921 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 12922 if (global_regattempts_max) 12923 p->registry->regattempts = global_regattempts_max+1; 12924 AST_SCHED_DEL(sched, r->timeout); 12925 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12926 break; 12927 case 404: /* Not found */ 12928 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 12929 if (global_regattempts_max) 12930 p->registry->regattempts = global_regattempts_max+1; 12931 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12932 r->call = NULL; 12933 AST_SCHED_DEL(sched, r->timeout); 12934 break; 12935 case 407: /* Proxy auth */ 12936 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 12937 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 12938 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12939 } 12940 break; 12941 case 408: /* Request timeout */ 12942 /* Got a timeout response, so reset the counter of failed responses */ 12943 if (r) { 12944 r->regattempts = 0; 12945 } else { 12946 ast_log(LOG_WARNING, "Got a 408 response to our REGISTER on call %s after we had destroyed the registry object\n", p->callid); 12947 } 12948 break; 12949 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 12950 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 12951 if (global_regattempts_max) 12952 p->registry->regattempts = global_regattempts_max+1; 12953 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12954 r->call = NULL; 12955 AST_SCHED_DEL(sched, r->timeout); 12956 break; 12957 case 200: /* 200 OK */ 12958 if (!r) { 12959 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)); 12960 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12961 return 0; 12962 } 12963 12964 r->regstate = REG_STATE_REGISTERED; 12965 r->regtime = time(NULL); /* Reset time of last succesful registration */ 12966 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 12967 r->regattempts = 0; 12968 if (option_debug) 12969 ast_log(LOG_DEBUG, "Registration successful\n"); 12970 if (r->timeout > -1) { 12971 if (option_debug) 12972 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 12973 } 12974 AST_SCHED_DEL(sched, r->timeout); 12975 r->call = NULL; 12976 p->registry = NULL; 12977 /* Let this one hang around until we have all the responses */ 12978 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12979 /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */ 12980 12981 /* set us up for re-registering */ 12982 /* figure out how long we got registered for */ 12983 AST_SCHED_DEL(sched, r->expire); 12984 /* according to section 6.13 of RFC, contact headers override 12985 expires headers, so check those first */ 12986 expires = 0; 12987 12988 /* XXX todo: try to save the extra call */ 12989 if (!ast_strlen_zero(get_header(req, "Contact"))) { 12990 const char *contact = NULL; 12991 const char *tmptmp = NULL; 12992 int start = 0; 12993 for(;;) { 12994 contact = __get_header(req, "Contact", &start); 12995 /* this loop ensures we get a contact header about our register request */ 12996 if(!ast_strlen_zero(contact)) { 12997 if( (tmptmp=strstr(contact, p->our_contact))) { 12998 contact=tmptmp; 12999 break; 13000 } 13001 } else 13002 break; 13003 } 13004 tmptmp = strcasestr(contact, "expires="); 13005 if (tmptmp) { 13006 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 13007 expires = 0; 13008 } 13009 13010 } 13011 if (!expires) 13012 expires=atoi(get_header(req, "expires")); 13013 if (!expires) 13014 expires=default_expiry; 13015 13016 expires_ms = expires * 1000; 13017 if (expires <= EXPIRY_GUARD_LIMIT) 13018 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 13019 else 13020 expires_ms -= EXPIRY_GUARD_SECS * 1000; 13021 if (sipdebug) 13022 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 13023 13024 r->refresh= (int) expires_ms / 1000; 13025 13026 /* Schedule re-registration before we expire */ 13027 AST_SCHED_DEL(sched, r->expire); 13028 r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 13029 ASTOBJ_UNREF(r, sip_registry_destroy); 13030 } 13031 return 1; 13032 }
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 3511 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().
03512 { 03513 switch (cause) { 03514 case AST_CAUSE_UNALLOCATED: /* 1 */ 03515 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 03516 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 03517 return "404 Not Found"; 03518 case AST_CAUSE_CONGESTION: /* 34 */ 03519 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 03520 return "503 Service Unavailable"; 03521 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 03522 return "408 Request Timeout"; 03523 case AST_CAUSE_NO_ANSWER: /* 19 */ 03524 case AST_CAUSE_UNREGISTERED: /* 20 */ 03525 return "480 Temporarily unavailable"; 03526 case AST_CAUSE_CALL_REJECTED: /* 21 */ 03527 return "403 Forbidden"; 03528 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 03529 return "410 Gone"; 03530 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 03531 return "480 Temporarily unavailable"; 03532 case AST_CAUSE_INVALID_NUMBER_FORMAT: 03533 return "484 Address incomplete"; 03534 case AST_CAUSE_USER_BUSY: 03535 return "486 Busy here"; 03536 case AST_CAUSE_FAILURE: 03537 return "500 Server internal failure"; 03538 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 03539 return "501 Not Implemented"; 03540 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 03541 return "503 Service Unavailable"; 03542 /* Used in chan_iax2 */ 03543 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 03544 return "502 Bad Gateway"; 03545 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 03546 return "488 Not Acceptable Here"; 03547 03548 case AST_CAUSE_NOTDEFINED: 03549 default: 03550 if (option_debug) 03551 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 03552 return NULL; 03553 } 03554 03555 /* Never reached */ 03556 return 0; 03557 }
static int hangup_sip2cause | ( | int | cause | ) | [static] |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 3399 of file chan_sip.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INTERWORKING, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, AST_CAUSE_UNALLOCATED, and AST_CAUSE_USER_BUSY.
Referenced by handle_response().
03400 { 03401 /* Possible values taken from causes.h */ 03402 03403 switch(cause) { 03404 case 401: /* Unauthorized */ 03405 return AST_CAUSE_CALL_REJECTED; 03406 case 403: /* Not found */ 03407 return AST_CAUSE_CALL_REJECTED; 03408 case 404: /* Not found */ 03409 return AST_CAUSE_UNALLOCATED; 03410 case 405: /* Method not allowed */ 03411 return AST_CAUSE_INTERWORKING; 03412 case 407: /* Proxy authentication required */ 03413 return AST_CAUSE_CALL_REJECTED; 03414 case 408: /* No reaction */ 03415 return AST_CAUSE_NO_USER_RESPONSE; 03416 case 409: /* Conflict */ 03417 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 03418 case 410: /* Gone */ 03419 return AST_CAUSE_UNALLOCATED; 03420 case 411: /* Length required */ 03421 return AST_CAUSE_INTERWORKING; 03422 case 413: /* Request entity too large */ 03423 return AST_CAUSE_INTERWORKING; 03424 case 414: /* Request URI too large */ 03425 return AST_CAUSE_INTERWORKING; 03426 case 415: /* Unsupported media type */ 03427 return AST_CAUSE_INTERWORKING; 03428 case 420: /* Bad extension */ 03429 return AST_CAUSE_NO_ROUTE_DESTINATION; 03430 case 480: /* No answer */ 03431 return AST_CAUSE_NO_ANSWER; 03432 case 481: /* No answer */ 03433 return AST_CAUSE_INTERWORKING; 03434 case 482: /* Loop detected */ 03435 return AST_CAUSE_INTERWORKING; 03436 case 483: /* Too many hops */ 03437 return AST_CAUSE_NO_ANSWER; 03438 case 484: /* Address incomplete */ 03439 return AST_CAUSE_INVALID_NUMBER_FORMAT; 03440 case 485: /* Ambigous */ 03441 return AST_CAUSE_UNALLOCATED; 03442 case 486: /* Busy everywhere */ 03443 return AST_CAUSE_BUSY; 03444 case 487: /* Request terminated */ 03445 return AST_CAUSE_INTERWORKING; 03446 case 488: /* No codecs approved */ 03447 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03448 case 491: /* Request pending */ 03449 return AST_CAUSE_INTERWORKING; 03450 case 493: /* Undecipherable */ 03451 return AST_CAUSE_INTERWORKING; 03452 case 500: /* Server internal failure */ 03453 return AST_CAUSE_FAILURE; 03454 case 501: /* Call rejected */ 03455 return AST_CAUSE_FACILITY_REJECTED; 03456 case 502: 03457 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03458 case 503: /* Service unavailable */ 03459 return AST_CAUSE_CONGESTION; 03460 case 504: /* Gateway timeout */ 03461 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 03462 case 505: /* SIP version not supported */ 03463 return AST_CAUSE_INTERWORKING; 03464 case 600: /* Busy everywhere */ 03465 return AST_CAUSE_USER_BUSY; 03466 case 603: /* Decline */ 03467 return AST_CAUSE_CALL_REJECTED; 03468 case 604: /* Does not exist anywhere */ 03469 return AST_CAUSE_UNALLOCATED; 03470 case 606: /* Not acceptable */ 03471 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03472 default: 03473 return AST_CAUSE_NORMAL; 03474 } 03475 /* Never reached */ 03476 return 0; 03477 }
static int init_req | ( | struct sip_request * | req, | |
int | sipmethod, | |||
const char * | recip | |||
) | [static] |
Initialize SIP request.
Definition at line 6037 of file chan_sip.c.
References sip_methods, and cfsip_methods::text.
06038 { 06039 /* Initialize a request */ 06040 memset(req, 0, sizeof(*req)); 06041 req->method = sipmethod; 06042 req->header[0] = req->data; 06043 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 06044 req->len = strlen(req->header[0]); 06045 req->headers++; 06046 return 0; 06047 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 6024 of file chan_sip.c.
References SIP_RESPONSE.
06025 { 06026 /* Initialize a response */ 06027 memset(resp, 0, sizeof(*resp)); 06028 resp->method = SIP_RESPONSE; 06029 resp->header[0] = resp->data; 06030 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 06031 resp->len = strlen(resp->header[0]); 06032 resp->headers++; 06033 return 0; 06034 }
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 1661 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().
01662 { 01663 if (p->initreq.headers && option_debug) { 01664 ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 01665 } 01666 /* Use this as the basis */ 01667 copy_request(&p->initreq, req); 01668 parse_request(&p->initreq); 01669 if (ast_test_flag(req, SIP_PKT_DEBUG)) 01670 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 01671 }
static void initreqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod | |||
) | [static] |
Initiate new SIP request to peer/user.
Definition at line 7190 of file chan_sip.c.
References add_header(), ast_build_string(), AST_DIGIT_ANYNUM, ast_inet_ntoa(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_encode(), build_contact(), build_rpid(), CALLERID_UNKNOWN, sip_pvt::callid, sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, DEFAULT_MAX_FORWARDS, exten, sip_pvt::flags, sip_pvt::fromdomain, sip_pvt::fromname, sip_pvt::fromuser, sip_pvt::fullcontact, init_req(), sip_pvt::lastmsg, sip_pvt::ocseq, sip_pvt::options, sip_pvt::our_contact, sip_pvt::ourip, ourport, sip_pvt::owner, sip_pvt::rpid, s, S_OR, sip_pvt::sa, SIP_INVITE, sip_methods, SIP_NOTIFY, SIP_SENDRPID, SIP_USEREQPHONE, SIPBUFSIZE, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, sip_pvt::tohost, sip_pvt::uri, sip_invite_param::uri_options, sip_pvt::username, sip_pvt::via, and sip_invite_param::vxml_url.
Referenced by sip_notify(), transmit_invite(), and transmit_notify_with_mwi().
07191 { 07192 char invite_buf[256] = ""; 07193 char *invite = invite_buf; 07194 size_t invite_max = sizeof(invite_buf); 07195 char from[256]; 07196 char to[256]; 07197 char tmp[SIPBUFSIZE/2]; 07198 char tmp2[SIPBUFSIZE/2]; 07199 const char *l = NULL, *n = NULL; 07200 const char *urioptions = ""; 07201 07202 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 07203 const char *s = p->username; /* being a string field, cannot be NULL */ 07204 07205 /* Test p->username against allowed characters in AST_DIGIT_ANY 07206 If it matches the allowed characters list, then sipuser = ";user=phone" 07207 If not, then sipuser = "" 07208 */ 07209 /* + is allowed in first position in a tel: uri */ 07210 if (*s == '+') 07211 s++; 07212 for (; *s; s++) { 07213 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 07214 break; 07215 } 07216 /* If we have only digits, add ;user=phone to the uri */ 07217 if (!*s) 07218 urioptions = ";user=phone"; 07219 } 07220 07221 07222 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 07223 07224 if (p->owner) { 07225 l = p->owner->cid.cid_num; 07226 n = p->owner->cid.cid_name; 07227 } 07228 /* if we are not sending RPID and user wants his callerid restricted */ 07229 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 07230 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 07231 l = CALLERID_UNKNOWN; 07232 n = l; 07233 } 07234 if (ast_strlen_zero(l)) 07235 l = default_callerid; 07236 if (ast_strlen_zero(n)) 07237 n = l; 07238 /* Allow user to be overridden */ 07239 if (!ast_strlen_zero(p->fromuser)) 07240 l = p->fromuser; 07241 else /* Save for any further attempts */ 07242 ast_string_field_set(p, fromuser, l); 07243 07244 /* Allow user to be overridden */ 07245 if (!ast_strlen_zero(p->fromname)) 07246 n = p->fromname; 07247 else /* Save for any further attempts */ 07248 ast_string_field_set(p, fromname, n); 07249 07250 if (pedanticsipchecking) { 07251 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07252 n = tmp; 07253 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 07254 l = tmp2; 07255 } 07256 07257 if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain)) 07258 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); 07259 else 07260 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag); 07261 07262 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 07263 if (!ast_strlen_zero(p->fullcontact)) { 07264 /* If we have full contact, trust it */ 07265 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 07266 } else { 07267 /* Otherwise, use the username while waiting for registration */ 07268 ast_build_string(&invite, &invite_max, "sip:"); 07269 if (!ast_strlen_zero(p->username)) { 07270 n = p->username; 07271 if (pedanticsipchecking) { 07272 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07273 n = tmp; 07274 } 07275 ast_build_string(&invite, &invite_max, "%s@", n); 07276 } 07277 ast_build_string(&invite, &invite_max, "%s", p->tohost); 07278 if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT) 07279 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 07280 ast_build_string(&invite, &invite_max, "%s", urioptions); 07281 } 07282 07283 /* If custom URI options have been provided, append them */ 07284 if (p->options && !ast_strlen_zero(p->options->uri_options)) 07285 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 07286 07287 ast_string_field_set(p, uri, invite_buf); 07288 07289 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 07290 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 07291 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (!strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag); 07292 } else if (p->options && p->options->vxml_url) { 07293 /* If there is a VXML URL append it to the SIP URL */ 07294 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 07295 } else 07296 snprintf(to, sizeof(to), "<%s>", p->uri); 07297 07298 init_req(req, sipmethod, p->uri); 07299 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 07300 07301 add_header(req, "Via", p->via); 07302 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 07303 * OTOH, then we won't have anything in p->route anyway */ 07304 /* Build Remote Party-ID and From */ 07305 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 07306 build_rpid(p); 07307 add_header(req, "From", p->rpid_from); 07308 } else 07309 add_header(req, "From", from); 07310 add_header(req, "To", to); 07311 ast_string_field_set(p, exten, l); 07312 build_contact(p); 07313 add_header(req, "Contact", p->our_contact); 07314 add_header(req, "Call-ID", p->callid); 07315 add_header(req, "CSeq", tmp); 07316 if (!ast_strlen_zero(global_useragent)) 07317 add_header(req, "User-Agent", global_useragent); 07318 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07319 if (!ast_strlen_zero(p->rpid)) 07320 add_header(req, "Remote-Party-ID", p->rpid); 07321 }
static const char * insecure2str | ( | int | port, | |
int | invite | |||
) | const [static] |
Convert Insecure setting to printable string.
Definition at line 10513 of file chan_sip.c.
Referenced by _sip_show_peer().
10514 { 10515 if (port && invite) 10516 return "port,invite"; 10517 else if (port) 10518 return "port"; 10519 else if (invite) 10520 return "invite"; 10521 else 10522 return "no"; 10523 }
static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 8556 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
08557 { 08558 if (!route) 08559 ast_verbose("list_route: no route\n"); 08560 else { 08561 for (;route; route = route->next) 08562 ast_verbose("list_route: hop: <%s>\n", route->hop); 08563 } 08564 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 19032 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.
19033 { 19034 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 19035 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 19036 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 19037 19038 if (!(sched = sched_context_create())) { 19039 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 19040 return AST_MODULE_LOAD_FAILURE; 19041 } 19042 19043 if (!(io = io_context_create())) { 19044 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 19045 sched_context_destroy(sched); 19046 return AST_MODULE_LOAD_FAILURE; 19047 } 19048 19049 sip_reloadreason = CHANNEL_MODULE_LOAD; 19050 19051 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 19052 return AST_MODULE_LOAD_DECLINE; 19053 19054 /* Make sure we can register our sip channel type */ 19055 if (ast_channel_register(&sip_tech)) { 19056 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 19057 io_context_destroy(io); 19058 sched_context_destroy(sched); 19059 return AST_MODULE_LOAD_FAILURE; 19060 } 19061 19062 /* Register all CLI functions for SIP */ 19063 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 19064 19065 /* Tell the RTP subdriver that we're here */ 19066 ast_rtp_proto_register(&sip_rtp); 19067 19068 /* Tell the UDPTL subdriver that we're here */ 19069 ast_udptl_proto_register(&sip_udptl); 19070 19071 /* Register dialplan applications */ 19072 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 19073 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 19074 19075 /* Register dialplan functions */ 19076 ast_custom_function_register(&sip_header_function); 19077 ast_custom_function_register(&sippeer_function); 19078 ast_custom_function_register(&sipchaninfo_function); 19079 ast_custom_function_register(&checksipdomain_function); 19080 19081 /* Register manager commands */ 19082 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 19083 "List SIP peers (text format)", mandescr_show_peers); 19084 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 19085 "Show SIP peer (text format)", mandescr_show_peer); 19086 19087 sip_poke_all_peers(); 19088 sip_send_all_registers(); 19089 19090 /* And start the monitor for the first time */ 19091 restart_monitor(); 19092 19093 return AST_MODULE_LOAD_SUCCESS; 19094 }
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 15015 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().
15016 { 15017 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 15018 /* Chan 2: Call from Asterisk to target */ 15019 int res = 0; 15020 struct sip_pvt *targetcall_pvt; 15021 15022 /* Check if the call ID of the replaces header does exist locally */ 15023 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 15024 transferer->refer->replaces_callid_fromtag))) { 15025 if (transferer->refer->localtransfer) { 15026 /* We did not find the refered call. Sorry, can't accept then */ 15027 transmit_response(transferer, "202 Accepted", req); 15028 /* Let's fake a response from someone else in order 15029 to follow the standard */ 15030 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 15031 append_history(transferer, "Xfer", "Refer failed"); 15032 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 15033 transferer->refer->status = REFER_FAILED; 15034 return -1; 15035 } 15036 /* Fall through for remote transfers that we did not find locally */ 15037 if (option_debug > 2) 15038 ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 15039 return 0; 15040 } 15041 15042 /* Ok, we can accept this transfer */ 15043 transmit_response(transferer, "202 Accepted", req); 15044 append_history(transferer, "Xfer", "Refer accepted"); 15045 if (!targetcall_pvt->owner) { /* No active channel */ 15046 if (option_debug > 3) 15047 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n"); 15048 /* Cancel transfer */ 15049 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 15050 append_history(transferer, "Xfer", "Refer failed"); 15051 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 15052 transferer->refer->status = REFER_FAILED; 15053 ast_mutex_unlock(&targetcall_pvt->lock); 15054 ast_channel_unlock(current->chan1); 15055 return -1; 15056 } 15057 15058 /* We have a channel, find the bridge */ 15059 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 15060 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 15061 15062 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 15063 /* Wrong state of new channel */ 15064 if (option_debug > 3) { 15065 if (target.chan2) 15066 ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 15067 else if (target.chan1->_state != AST_STATE_RING) 15068 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n"); 15069 else 15070 ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n"); 15071 } 15072 } 15073 15074 /* Transfer */ 15075 if (option_debug > 3 && sipdebug) { 15076 if (current->chan2) /* We have two bridges */ 15077 ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 15078 else /* One bridge, propably transfer of IVR/voicemail etc */ 15079 ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 15080 } 15081 15082 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 15083 15084 /* Perform the transfer */ 15085 res = attempt_transfer(current, &target); 15086 ast_mutex_unlock(&targetcall_pvt->lock); 15087 if (res) { 15088 /* Failed transfer */ 15089 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 15090 append_history(transferer, "Xfer", "Refer failed"); 15091 transferer->refer->status = REFER_FAILED; 15092 if (targetcall_pvt->owner) 15093 ast_channel_unlock(targetcall_pvt->owner); 15094 /* Right now, we have to hangup, sorry. Bridge is destroyed */ 15095 if (res != -2) 15096 ast_hangup(transferer->owner); 15097 else 15098 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 15099 } else { 15100 /* Transfer succeeded! */ 15101 15102 /* Tell transferer that we're done. */ 15103 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 15104 append_history(transferer, "Xfer", "Refer succeeded"); 15105 transferer->refer->status = REFER_200OK; 15106 if (targetcall_pvt->owner) { 15107 if (option_debug) 15108 ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 15109 ast_channel_unlock(targetcall_pvt->owner); 15110 } 15111 } 15112 return 1; 15113 }
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 4893 of file chan_sip.c.
References t.
Referenced by sipsock_read().
04894 { 04895 int h = 0, t = 0; 04896 int lws = 0; 04897 04898 for (; h < len;) { 04899 /* Eliminate all CRs */ 04900 if (msgbuf[h] == '\r') { 04901 h++; 04902 continue; 04903 } 04904 /* Check for end-of-line */ 04905 if (msgbuf[h] == '\n') { 04906 /* Check for end-of-message */ 04907 if (h + 1 == len) 04908 break; 04909 /* Check for a continuation line */ 04910 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 04911 /* Merge continuation line */ 04912 h++; 04913 continue; 04914 } 04915 /* Propagate LF and start new line */ 04916 msgbuf[t++] = msgbuf[h++]; 04917 lws = 0; 04918 continue; 04919 } 04920 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 04921 if (lws) { 04922 h++; 04923 continue; 04924 } 04925 msgbuf[t++] = msgbuf[h++]; 04926 lws = 1; 04927 continue; 04928 } 04929 msgbuf[t++] = msgbuf[h++]; 04930 if (lws) 04931 lws = 0; 04932 } 04933 msgbuf[t] = '\0'; 04934 return t; 04935 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Make our SIP dialog tag.
Definition at line 4557 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().
04558 { 04559 snprintf(tagbuf, len, "as%08lx", ast_random()); 04560 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10758 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().
10759 { 10760 const char *a[4]; 10761 const char *peer; 10762 int ret; 10763 10764 peer = astman_get_header(m,"Peer"); 10765 if (ast_strlen_zero(peer)) { 10766 astman_send_error(s, m, "Peer: <name> missing."); 10767 return 0; 10768 } 10769 a[0] = "sip"; 10770 a[1] = "show"; 10771 a[2] = "peer"; 10772 a[3] = peer; 10773 10774 ret = _sip_show_peer(1, -1, s, m, 4, a); 10775 astman_append(s, "\r\n\r\n" ); 10776 return ret; 10777 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10309 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().
10310 { 10311 const char *id = astman_get_header(m,"ActionID"); 10312 const char *a[] = {"sip", "show", "peers"}; 10313 char idtext[256] = ""; 10314 int total = 0; 10315 10316 if (!ast_strlen_zero(id)) 10317 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 10318 10319 astman_send_ack(s, m, "Peer status list will follow"); 10320 /* List the peers in separate manager events */ 10321 _sip_show_peers(-1, &total, s, m, 3, a); 10322 /* Send final confirmation */ 10323 astman_append(s, 10324 "Event: PeerlistComplete\r\n" 10325 "ListItems: %d\r\n" 10326 "%s" 10327 "\r\n", total, idtext); 10328 return 0; 10329 }
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 1687 of file chan_sip.c.
References sip_request::len, sip_methods, and text.
Referenced by __sip_semi_ack(), and find_sip_method().
01688 { 01689 int len = strlen(sip_methods[id].text); 01690 int l_name = name ? strlen(name) : 0; 01691 /* true if the string is long enough, and ends with whitespace, and matches */ 01692 return (l_name >= len && name[len] < 33 && 01693 !strncasecmp(sip_methods[id].text, name, len)); 01694 }
static char * nat2str | ( | int | nat | ) | const [static] |
Convert NAT setting to text string.
Definition at line 10212 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().
10213 { 10214 switch(nat) { 10215 case SIP_NAT_NEVER: 10216 return "No"; 10217 case SIP_NAT_ROUTE: 10218 return "Route"; 10219 case SIP_NAT_ALWAYS: 10220 return "Always"; 10221 case SIP_NAT_RFC3581: 10222 return "RFC3581"; 10223 default: 10224 return "Unknown"; 10225 } 10226 }
static void parse_copy | ( | struct sip_request * | dst, | |
const struct sip_request * | src | |||
) | [static] |
Copy SIP request, parse it.
Definition at line 2273 of file chan_sip.c.
References sip_request::data, sip_request::len, and parse_request().
Referenced by send_request(), and send_response().
02274 { 02275 memset(dst, 0, sizeof(*dst)); 02276 memcpy(dst->data, src->data, sizeof(dst->data)); 02277 dst->len = src->len; 02278 parse_request(dst); 02279 }
static void parse_moved_contact | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Parse 302 Moved temporalily response.
Definition at line 12414 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().
12415 { 12416 char tmp[SIPBUFSIZE]; 12417 char *s, *e, *uri, *t; 12418 char *domain; 12419 12420 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 12421 if ((t = strchr(tmp, ','))) 12422 *t = '\0'; 12423 s = get_in_brackets(tmp); 12424 uri = ast_strdupa(s); 12425 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 12426 if (!strncasecmp(s, "sip:", 4)) 12427 s += 4; 12428 e = strchr(s, ';'); 12429 if (e) 12430 *e = '\0'; 12431 if (option_debug) 12432 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 12433 if (p->owner) 12434 ast_string_field_build(p->owner, call_forward, "SIP/%s", s); 12435 } else { 12436 e = strchr(tmp, '@'); 12437 if (e) { 12438 *e++ = '\0'; 12439 domain = e; 12440 } else { 12441 /* No username part */ 12442 domain = tmp; 12443 } 12444 e = strchr(s, ';'); /* Strip of parameters in the username part */ 12445 if (e) 12446 *e = '\0'; 12447 e = strchr(domain, ';'); /* Strip of parameters in the domain part */ 12448 if (e) 12449 *e = '\0'; 12450 12451 if (!strncasecmp(s, "sip:", 4)) 12452 s += 4; 12453 if (option_debug > 1) 12454 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 12455 if (p->owner) { 12456 pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri); 12457 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 12458 ast_string_field_set(p->owner, call_forward, s); 12459 } 12460 } 12461 }
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 8285 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().
08286 { 08287 char contact[SIPBUFSIZE]; 08288 char *c; 08289 08290 /* Look for brackets */ 08291 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08292 c = get_in_brackets(contact); 08293 08294 /* Save full contact to call pvt for later bye or re-invite */ 08295 ast_string_field_set(pvt, fullcontact, c); 08296 08297 /* Save URI for later ACKs, BYE or RE-invites */ 08298 ast_string_field_set(pvt, okcontacturi, c); 08299 08300 /* We should return false for URI:s we can't handle, 08301 like sips:, tel:, mailto:,ldap: etc */ 08302 return TRUE; 08303 }
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 8374 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().
08375 { 08376 char contact[SIPBUFSIZE]; 08377 char data[SIPBUFSIZE]; 08378 const char *expires = get_header(req, "Expires"); 08379 int expiry = atoi(expires); 08380 char *curi, *n, *pt; 08381 int port; 08382 const char *useragent; 08383 struct hostent *hp; 08384 struct ast_hostent ahp; 08385 struct sockaddr_in oldsin, testsin; 08386 08387 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08388 08389 if (ast_strlen_zero(expires)) { /* No expires header */ 08390 expires = strcasestr(contact, ";expires="); 08391 if (expires) { 08392 /* XXX bug here, we overwrite the string */ 08393 expires = strsep((char **) &expires, ";"); /* trim ; and beyond */ 08394 if (sscanf(expires + 9, "%d", &expiry) != 1) 08395 expiry = default_expiry; 08396 } else { 08397 /* Nothing has been specified */ 08398 expiry = default_expiry; 08399 } 08400 } 08401 08402 /* Look for brackets */ 08403 curi = contact; 08404 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 08405 strsep(&curi, ";"); /* This is Header options, not URI options */ 08406 curi = get_in_brackets(contact); 08407 08408 /* if they did not specify Contact: or Expires:, they are querying 08409 what we currently have stored as their contact address, so return 08410 it 08411 */ 08412 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 08413 /* If we have an active registration, tell them when the registration is going to expire */ 08414 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 08415 pvt->expiry = ast_sched_when(sched, peer->expire); 08416 return PARSE_REGISTER_QUERY; 08417 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 08418 /* This means remove all registrations and return OK */ 08419 memset(&peer->addr, 0, sizeof(peer->addr)); 08420 if (!AST_SCHED_DEL(sched, peer->expire)) { 08421 struct sip_peer *peer_ptr = peer; 08422 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08423 } 08424 08425 destroy_association(peer); 08426 08427 register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */ 08428 peer->fullcontact[0] = '\0'; 08429 peer->useragent[0] = '\0'; 08430 peer->sipoptions = 0; 08431 peer->lastms = 0; 08432 pvt->expiry = 0; 08433 08434 if (option_verbose > 2) 08435 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name); 08436 08437 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name); 08438 return PARSE_REGISTER_UPDATE; 08439 } 08440 08441 /* Store whatever we got as a contact from the client */ 08442 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 08443 08444 /* For the 200 OK, we should use the received contact */ 08445 ast_string_field_build(pvt, our_contact, "<%s>", curi); 08446 08447 /* Make sure it's a SIP URL */ 08448 if (strncasecmp(curi, "sip:", 4)) { 08449 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 08450 } else 08451 curi += 4; 08452 /* Ditch q */ 08453 curi = strsep(&curi, ";"); 08454 /* Grab host */ 08455 n = strchr(curi, '@'); 08456 if (!n) { 08457 n = curi; 08458 curi = NULL; 08459 } else 08460 *n++ = '\0'; 08461 pt = strchr(n, ':'); 08462 if (pt) { 08463 *pt++ = '\0'; 08464 port = atoi(pt); 08465 } else 08466 port = STANDARD_SIP_PORT; 08467 oldsin = peer->addr; 08468 08469 /* Check that they're allowed to register at this IP */ 08470 /* XXX This could block for a long time XXX */ 08471 hp = ast_gethostbyname(n, &ahp); 08472 if (!hp) { 08473 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 08474 *peer->fullcontact = '\0'; 08475 ast_string_field_set(pvt, our_contact, ""); 08476 return PARSE_REGISTER_FAILED; 08477 } 08478 memcpy(&testsin.sin_addr, hp->h_addr, sizeof(testsin.sin_addr)); 08479 if ( ast_apply_ha(global_contact_ha, &testsin) != AST_SENSE_ALLOW || 08480 ast_apply_ha(peer->contactha, &testsin) != AST_SENSE_ALLOW) { 08481 ast_log(LOG_WARNING, "Host '%s' disallowed by rule\n", n); 08482 *peer->fullcontact = '\0'; 08483 ast_string_field_set(pvt, our_contact, ""); 08484 return PARSE_REGISTER_FAILED; 08485 } 08486 08487 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 08488 peer->addr.sin_family = AF_INET; 08489 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 08490 peer->addr.sin_port = htons(port); 08491 } else { 08492 /* Don't trust the contact field. Just use what they came to us 08493 with */ 08494 peer->addr = pvt->recv; 08495 } 08496 08497 /* Save SIP options profile */ 08498 peer->sipoptions = pvt->sipoptions; 08499 08500 if (curi && ast_strlen_zero(peer->username)) 08501 ast_copy_string(peer->username, curi, sizeof(peer->username)); 08502 08503 if (!AST_SCHED_DEL(sched, peer->expire)) { 08504 struct sip_peer *peer_ptr = peer; 08505 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08506 } 08507 if (expiry > max_expiry) 08508 expiry = max_expiry; 08509 if (expiry < min_expiry) 08510 expiry = min_expiry; 08511 if (ast_test_flag(&peer->flags[0], SIP_REALTIME) && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 08512 peer->expire = -1; 08513 } else { 08514 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08515 if (peer->expire == -1) { 08516 struct sip_peer *peer_ptr = peer; 08517 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08518 } 08519 } 08520 pvt->expiry = expiry; 08521 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); 08522 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08523 ast_db_put("SIP/Registry", peer->name, data); 08524 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08525 08526 /* Is this a new IP address for us? */ 08527 if (option_verbose > 2 && inaddrcmp(&peer->addr, &oldsin)) { 08528 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)); 08529 } 08530 sip_poke_peer(peer); 08531 register_peer_exten(peer, 1); 08532 08533 /* Save User agent */ 08534 useragent = get_header(req, "User-Agent"); 08535 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 08536 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 08537 if (option_verbose > 3) 08538 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 08539 } 08540 return PARSE_REGISTER_UPDATE; 08541 }
static int parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 4940 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().
04941 { 04942 /* Divide fields by NULL's */ 04943 char *c; 04944 int f = 0; 04945 04946 c = req->data; 04947 04948 /* First header starts immediately */ 04949 req->header[f] = c; 04950 while(*c) { 04951 if (*c == '\n') { 04952 /* We've got a new header */ 04953 *c = 0; 04954 04955 if (sipdebug && option_debug > 3) 04956 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04957 if (ast_strlen_zero(req->header[f])) { 04958 /* Line by itself means we're now in content */ 04959 c++; 04960 break; 04961 } 04962 if (f >= SIP_MAX_HEADERS - 1) { 04963 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 04964 } else { 04965 f++; 04966 req->header[f] = c + 1; 04967 } 04968 } else if (*c == '\r') { 04969 /* Ignore but eliminate \r's */ 04970 *c = 0; 04971 } 04972 c++; 04973 } 04974 04975 req->headers = f; 04976 04977 /* Check a non-newline-terminated last header */ 04978 if (!ast_strlen_zero(req->header[f])) { 04979 if (sipdebug && option_debug > 3) 04980 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04981 req->headers++; 04982 } 04983 04984 /* Now we process any body content */ 04985 f = 0; 04986 req->line[f] = c; 04987 while (*c) { 04988 if (*c == '\n') { 04989 /* We've got a new line */ 04990 *c = 0; 04991 if (sipdebug && option_debug > 3) 04992 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 04993 if (f == SIP_MAX_LINES - 1) { 04994 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 04995 break; 04996 } else { 04997 f++; 04998 req->line[f] = c + 1; 04999 } 05000 } else if (*c == '\r') { 05001 /* Ignore and eliminate \r's */ 05002 *c = 0; 05003 } 05004 c++; 05005 } 05006 05007 req->lines = f; 05008 05009 /* Check a non-newline-terminated last line */ 05010 if (!ast_strlen_zero(req->line[f])) { 05011 req->lines++; 05012 } 05013 05014 if (*c) 05015 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 05016 05017 /* Split up the first line parts */ 05018 return determine_firstline_parts(req); 05019 }
static unsigned int parse_sip_options | ( | struct sip_pvt * | pvt, | |
const char * | supported | |||
) | [static] |
Parse supported header in incoming packet.
Definition at line 1711 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().
01712 { 01713 char *next, *sep; 01714 char *temp; 01715 unsigned int profile = 0; 01716 int i, found; 01717 01718 if (ast_strlen_zero(supported) ) 01719 return 0; 01720 temp = ast_strdupa(supported); 01721 01722 if (option_debug > 2 && sipdebug) 01723 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01724 01725 for (next = temp; next; next = sep) { 01726 found = FALSE; 01727 if ( (sep = strchr(next, ',')) != NULL) 01728 *sep++ = '\0'; 01729 next = ast_skip_blanks(next); 01730 if (option_debug > 2 && sipdebug) 01731 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01732 for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) { 01733 if (!strcasecmp(next, sip_options[i].text)) { 01734 profile |= sip_options[i].id; 01735 found = TRUE; 01736 if (option_debug > 2 && sipdebug) 01737 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01738 break; 01739 } 01740 } 01741 if (!found && option_debug > 2 && sipdebug) { 01742 if (!strncasecmp(next, "x-", 2)) 01743 ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next); 01744 else 01745 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01746 } 01747 } 01748 01749 if (pvt) 01750 pvt->sipoptions = profile; 01751 return profile; 01752 }
static int peer_status | ( | struct sip_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
Report Peer status in character string.
Definition at line 10231 of file chan_sip.c.
References ast_copy_string(), sip_peer::lastms, and sip_peer::maxms.
10232 { 10233 int res = 0; 10234 if (peer->maxms) { 10235 if (peer->lastms < 0) { 10236 ast_copy_string(status, "UNREACHABLE", statuslen); 10237 } else if (peer->lastms > peer->maxms) { 10238 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 10239 res = 1; 10240 } else if (peer->lastms) { 10241 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 10242 res = 1; 10243 } else { 10244 ast_copy_string(status, "UNKNOWN", statuslen); 10245 } 10246 } else { 10247 ast_copy_string(status, "Unmonitored", statuslen); 10248 /* Checking if port is 0 */ 10249 res = -1; 10250 } 10251 return res; 10252 }
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 10699 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().
10700 { 10701 int x, codec; 10702 10703 for(x = 0; x < 32 ; x++) { 10704 codec = ast_codec_pref_index(pref, x); 10705 if (!codec) 10706 break; 10707 ast_cli(fd, "%s", ast_getformatname(codec)); 10708 ast_cli(fd, ":%d", pref->framing[x]); 10709 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 10710 ast_cli(fd, ","); 10711 } 10712 if (!x) 10713 ast_cli(fd, "none"); 10714 }
static void print_group | ( | int | fd, | |
ast_group_t | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 10490 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
10491 { 10492 char buf[256]; 10493 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 10494 }
static void process_request_queue | ( | struct sip_pvt * | p, | |
int * | recount, | |||
int * | nounlock | |||
) | [static] |
Definition at line 16215 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().
16216 { 16217 struct sip_request *req; 16218 16219 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 16220 if (handle_request(p, req, &p->recv, recount, nounlock) == -1) { 16221 /* Request failed */ 16222 if (option_debug) { 16223 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 16224 } 16225 } 16226 ast_free(req); 16227 } 16228 }
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 5152 of file chan_sip.c.
References ast_clear_flag, ast_codec_choose(), ast_codec_pref_setsize(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_FORMAT_AUDIO_MASK, ast_getformatname_multiple(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_control_data(), ast_queue_frame(), ast_rtp_alloc_size(), ast_rtp_codec_getformat(), ast_rtp_codec_getpref(), ast_rtp_codec_setpref(), AST_RTP_DTMF, ast_rtp_get_current_formats(), ast_rtp_get_peer(), ast_rtp_lookup_mime_multiple(), ast_rtp_new_init(), AST_RTP_OPT_G726_NONSTANDARD, ast_rtp_pt_clear(), ast_rtp_pt_copy(), ast_rtp_set_m_type(), ast_rtp_set_peer(), ast_rtp_set_rtpmap_type(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_stop(), ast_rtp_unset_m_type(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_threadstorage_get(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_local_max_datagram(), ast_udptl_set_peer(), ast_udptl_stop(), ast_verbose(), sip_pvt::autoframing, sip_pvt::callid, sip_pvt::capability, t38properties::capability, change_hold_state(), debug, FALSE, sip_pvt::flags, format, get_sdp(), get_sdp_iterate(), hp, sip_pvt::jointcapability, t38properties::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastinvite, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len(), LOG_DEBUG, LOG_ERROR, LOG_NOTICE, MAX_RTP_PT, sip_pvt::mohsuggest, ast_channel::name, ast_channel::nativeformats, sip_pvt::noncodeccapability, option_debug, sip_pvt::owner, sip_pvt::peercapability, t38properties::peercapability, portno, sip_pvt::prefs, ast_channel::readformat, sip_pvt::rtp, s, S_OR, SDP_MAX_RTPMAP_CODECS, sip_request::sdp_start, sip_debug_test_pvt(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_G726_NONSTANDARD, SIP_NAT, SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_UDPTL_DESTINATION, SIPBUFSIZE, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_PEER_DIRECT, T38_PEER_REINVITE, T38FAX_FILL_BIT_REMOVAL, T38FAX_RATE_12000, T38FAX_RATE_14400, T38FAX_RATE_2400, T38FAX_RATE_4800, T38FAX_RATE_7200, T38FAX_RATE_9600, T38FAX_RATE_MANAGEMENT_LOCAL_TCF, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_TRANSCODING_JBIG, T38FAX_TRANSCODING_MMR, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, T38FAX_VERSION_0, T38FAX_VERSION_1, TRUE, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, sip_pvt::vrtp, and ast_channel::writeformat.
05153 { 05154 const char *m; /* SDP media offer */ 05155 const char *c; 05156 const char *a; 05157 char host[258]; 05158 int len = -1; 05159 int portno = -1; /*!< RTP Audio port number */ 05160 int vportno = -1; /*!< RTP Video port number */ 05161 int udptlportno = -1; 05162 int peert38capability = 0; 05163 char s[256]; 05164 int old = 0; 05165 05166 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 05167 int peercapability = 0, peernoncodeccapability = 0; 05168 int vpeercapability = 0, vpeernoncodeccapability = 0; 05169 struct sockaddr_in sin; /*!< media socket address */ 05170 struct sockaddr_in vsin; /*!< Video socket address */ 05171 05172 const char *codecs; 05173 struct hostent *hp; /*!< RTP Audio host IP */ 05174 struct hostent *vhp = NULL; /*!< RTP video host IP */ 05175 struct ast_hostent audiohp; 05176 struct ast_hostent videohp; 05177 int codec; 05178 int destiterator = 0; 05179 int iterator; 05180 int sendonly = -1; 05181 int numberofports; 05182 struct ast_rtp *newaudiortp, *newvideortp; /* Buffers for codec handling */ 05183 int newjointcapability; /* Negotiated capability */ 05184 int newpeercapability; 05185 int newnoncodeccapability; 05186 int numberofmediastreams = 0; 05187 int debug = sip_debug_test_pvt(p); 05188 05189 int found_rtpmap_codecs[SDP_MAX_RTPMAP_CODECS]; 05190 int last_rtpmap_codec=0; 05191 05192 if (!p->rtp) { 05193 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 05194 return -1; 05195 } 05196 05197 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 05198 #ifdef LOW_MEMORY 05199 newaudiortp = ast_threadstorage_get(&ts_audio_rtp, ast_rtp_alloc_size()); 05200 #else 05201 newaudiortp = alloca(ast_rtp_alloc_size()); 05202 #endif 05203 memset(newaudiortp, 0, ast_rtp_alloc_size()); 05204 ast_rtp_new_init(newaudiortp); 05205 ast_rtp_pt_clear(newaudiortp); 05206 05207 #ifdef LOW_MEMORY 05208 newvideortp = ast_threadstorage_get(&ts_video_rtp, ast_rtp_alloc_size()); 05209 #else 05210 newvideortp = alloca(ast_rtp_alloc_size()); 05211 #endif 05212 memset(newvideortp, 0, ast_rtp_alloc_size()); 05213 ast_rtp_new_init(newvideortp); 05214 ast_rtp_pt_clear(newvideortp); 05215 05216 /* Update our last rtprx when we receive an SDP, too */ 05217 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 05218 05219 05220 /* Try to find first media stream */ 05221 m = get_sdp(req, "m"); 05222 destiterator = req->sdp_start; 05223 c = get_sdp_iterate(&destiterator, req, "c"); 05224 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 05225 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 05226 return -1; 05227 } 05228 05229 /* Check for IPv4 address (not IPv6 yet) */ 05230 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05231 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 05232 return -1; 05233 } 05234 05235 /* XXX This could block for a long time, and block the main thread! XXX */ 05236 hp = ast_gethostbyname(host, &audiohp); 05237 if (!hp) { 05238 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 05239 return -1; 05240 } 05241 vhp = hp; /* Copy to video address as default too */ 05242 05243 iterator = req->sdp_start; 05244 ast_set_flag(&p->flags[0], SIP_NOVIDEO); 05245 05246 05247 /* Find media streams in this SDP offer */ 05248 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 05249 int x; 05250 int audio = FALSE; 05251 05252 numberofports = 1; 05253 len = -1; 05254 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05255 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1 && len > 0)) { 05256 audio = TRUE; 05257 numberofmediastreams++; 05258 /* Found audio stream in this media definition */ 05259 portno = x; 05260 /* Scan through the RTP payload types specified in a "m=" line: */ 05261 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05262 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05263 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05264 return -1; 05265 } 05266 if (debug) 05267 ast_verbose("Found RTP audio format %d\n", codec); 05268 ast_rtp_set_m_type(newaudiortp, codec); 05269 } 05270 } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05271 (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1 && len >= 0)) { 05272 /* If it is not audio - is it video ? */ 05273 ast_clear_flag(&p->flags[0], SIP_NOVIDEO); 05274 numberofmediastreams++; 05275 vportno = x; 05276 /* Scan through the RTP payload types specified in a "m=" line: */ 05277 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05278 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05279 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05280 return -1; 05281 } 05282 if (debug) 05283 ast_verbose("Found RTP video format %d\n", codec); 05284 ast_rtp_set_m_type(newvideortp, codec); 05285 } 05286 } else if (p->udptl && ( (sscanf(m, "image %d udptl t38%n", &x, &len) == 1 && len > 0) || 05287 (sscanf(m, "image %d UDPTL t38%n", &x, &len) == 1 && len >= 0) )) { 05288 if (debug) 05289 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 05290 udptlportno = x; 05291 numberofmediastreams++; 05292 05293 if (p->owner && p->lastinvite) { 05294 p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ 05295 if (option_debug > 1) 05296 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); 05297 } else { 05298 p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ 05299 if (option_debug > 1) 05300 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05301 } 05302 } else 05303 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 05304 if (numberofports > 1) 05305 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 05306 05307 05308 /* Check for Media-description-level-address for audio */ 05309 c = get_sdp_iterate(&destiterator, req, "c"); 05310 if (!ast_strlen_zero(c)) { 05311 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05312 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 05313 } else { 05314 /* XXX This could block for a long time, and block the main thread! XXX */ 05315 if (audio) { 05316 if ( !(hp = ast_gethostbyname(host, &audiohp))) { 05317 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c); 05318 return -2; 05319 } 05320 } else if (!(vhp = ast_gethostbyname(host, &videohp))) { 05321 ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c); 05322 return -2; 05323 } 05324 } 05325 05326 } 05327 } 05328 if (portno == -1 && vportno == -1 && udptlportno == -1) 05329 /* No acceptable offer found in SDP - we have no ports */ 05330 /* Do not change RTP or VRTP if this is a re-invite */ 05331 return -2; 05332 05333 if (numberofmediastreams > 2) 05334 /* We have too many fax, audio and/or video media streams, fail this offer */ 05335 return -3; 05336 05337 /* RTP addresses and ports for audio and video */ 05338 sin.sin_family = AF_INET; 05339 vsin.sin_family = AF_INET; 05340 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 05341 if (vhp) 05342 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 05343 05344 /* Setup UDPTL port number */ 05345 if (p->udptl) { 05346 if (udptlportno > 0) { 05347 sin.sin_port = htons(udptlportno); 05348 if (ast_test_flag(&p->flags[0], SIP_NAT) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) { 05349 struct sockaddr_in peer; 05350 ast_rtp_get_peer(p->rtp, &peer); 05351 if (peer.sin_addr.s_addr) { 05352 memcpy(&sin.sin_addr, &peer.sin_addr, sizeof(sin.sin_addr)); 05353 if (debug) { 05354 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)); 05355 } 05356 } 05357 } 05358 ast_udptl_set_peer(p->udptl, &sin); 05359 if (debug) 05360 ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05361 } else { 05362 ast_udptl_stop(p->udptl); 05363 if (debug) 05364 ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n"); 05365 } 05366 } 05367 05368 05369 if (p->rtp) { 05370 if (portno > 0) { 05371 sin.sin_port = htons(portno); 05372 ast_rtp_set_peer(p->rtp, &sin); 05373 if (debug) 05374 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05375 } else { 05376 if (udptlportno > 0) { 05377 if (debug) 05378 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session. Callid %s\n", p->callid); 05379 } else { 05380 ast_rtp_stop(p->rtp); 05381 if (debug) 05382 ast_verbose("Peer doesn't provide audio. Callid %s\n", p->callid); 05383 } 05384 } 05385 } 05386 /* Setup video port number */ 05387 if (vportno != -1) 05388 vsin.sin_port = htons(vportno); 05389 05390 /* Next, scan through each "a=rtpmap:" line, noting each 05391 * specified RTP payload type (with corresponding MIME subtype): 05392 */ 05393 /* XXX This needs to be done per media stream, since it's media stream specific */ 05394 iterator = req->sdp_start; 05395 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05396 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 05397 if (option_debug > 1) { 05398 int breakout = FALSE; 05399 05400 /* If we're debugging, check for unsupported sdp options */ 05401 if (!strncasecmp(a, "rtcp:", (size_t) 5)) { 05402 if (debug) 05403 ast_verbose("Got unsupported a:rtcp in SDP offer \n"); 05404 breakout = TRUE; 05405 } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) { 05406 /* Format parameters: Not supported */ 05407 /* Note: This is used for codec parameters, like bitrate for 05408 G722 and video formats for H263 and H264 05409 See RFC2327 for an example */ 05410 if (debug) 05411 ast_verbose("Got unsupported a:fmtp in SDP offer \n"); 05412 breakout = TRUE; 05413 } else if (!strncasecmp(a, "framerate:", (size_t) 10)) { 05414 /* Video stuff: Not supported */ 05415 if (debug) 05416 ast_verbose("Got unsupported a:framerate in SDP offer \n"); 05417 breakout = TRUE; 05418 } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) { 05419 /* Video stuff: Not supported */ 05420 if (debug) 05421 ast_verbose("Got unsupported a:maxprate in SDP offer \n"); 05422 breakout = TRUE; 05423 } else if (!strncasecmp(a, "crypto:", (size_t) 7)) { 05424 /* SRTP stuff, not yet supported */ 05425 if (debug) 05426 ast_verbose("Got unsupported a:crypto in SDP offer \n"); 05427 breakout = TRUE; 05428 } 05429 if (breakout) /* We have a match, skip to next header */ 05430 continue; 05431 } 05432 if (!strcasecmp(a, "sendonly")) { 05433 if (sendonly == -1) 05434 sendonly = 1; 05435 continue; 05436 } else if (!strcasecmp(a, "inactive")) { 05437 if (sendonly == -1) 05438 sendonly = 2; 05439 continue; 05440 } else if (!strcasecmp(a, "sendrecv")) { 05441 if (sendonly == -1) 05442 sendonly = 0; 05443 continue; 05444 } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 05445 char *tmp = strrchr(a, ':'); 05446 long int framing = 0; 05447 if (tmp) { 05448 tmp++; 05449 framing = strtol(tmp, NULL, 10); 05450 if (framing == LONG_MIN || framing == LONG_MAX) { 05451 framing = 0; 05452 if (option_debug) 05453 ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a); 05454 } 05455 } 05456 if (framing && p->autoframing) { 05457 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 05458 int codec_n; 05459 int format = 0; 05460 for (codec_n = 0; codec_n < MAX_RTP_PT; codec_n++) { 05461 format = ast_rtp_codec_getformat(codec_n); 05462 if (!format) /* non-codec or not found */ 05463 continue; 05464 if (option_debug) 05465 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 05466 ast_codec_pref_setsize(pref, format, framing); 05467 } 05468 ast_rtp_codec_setpref(p->rtp, pref); 05469 } 05470 continue; 05471 } else if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) == 2) { 05472 /* We have a rtpmap to handle */ 05473 int found = FALSE; 05474 /* We should propably check if this is an audio or video codec 05475 so we know where to look */ 05476 05477 if (last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 05478 /* Note: should really look at the 'freq' and '#chans' params too */ 05479 if(ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 05480 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) { 05481 if (debug) 05482 ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec); 05483 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05484 last_rtpmap_codec++; 05485 found = TRUE; 05486 05487 } else if (p->vrtp) { 05488 if(ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) { 05489 if (debug) 05490 ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec); 05491 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05492 last_rtpmap_codec++; 05493 found = TRUE; 05494 } 05495 } 05496 } else { 05497 if (debug) 05498 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 05499 } 05500 05501 if (!found) { 05502 /* Remove this codec since it's an unknown media type for us */ 05503 /* XXX This is buggy since the media line for audio and video can have the 05504 same numbers. We need to check as described above, but for testing this works... */ 05505 ast_rtp_unset_m_type(newaudiortp, codec); 05506 ast_rtp_unset_m_type(newvideortp, codec); 05507 if (debug) 05508 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 05509 } 05510 } 05511 } 05512 05513 if (udptlportno != -1) { 05514 int found = 0, x; 05515 05516 old = 0; 05517 05518 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 05519 iterator = req->sdp_start; 05520 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05521 if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) { 05522 found = 1; 05523 if (option_debug > 2) 05524 ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x); 05525 } else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1) || (sscanf(a, "T38FaxMaxRate:%d", &x) == 1)) { 05526 found = 1; 05527 if (option_debug > 2) 05528 ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x); 05529 switch (x) { 05530 case 14400: 05531 peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05532 break; 05533 case 12000: 05534 peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05535 break; 05536 case 9600: 05537 peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05538 break; 05539 case 7200: 05540 peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05541 break; 05542 case 4800: 05543 peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 05544 break; 05545 case 2400: 05546 peert38capability |= T38FAX_RATE_2400; 05547 break; 05548 } 05549 } else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) { 05550 found = 1; 05551 if (option_debug > 2) 05552 ast_log(LOG_DEBUG, "FaxVersion: %d\n",x); 05553 if (x == 0) 05554 peert38capability |= T38FAX_VERSION_0; 05555 else if (x == 1) 05556 peert38capability |= T38FAX_VERSION_1; 05557 } else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1) || (sscanf(a, "T38MaxDatagram:%d", &x) == 1)) { 05558 found = 1; 05559 if (option_debug > 2) 05560 ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x); 05561 ast_udptl_set_far_max_datagram(p->udptl, x); 05562 ast_udptl_set_local_max_datagram(p->udptl, x); 05563 } else if ((strncmp(a, "T38FaxFillBitRemoval", 20) == 0)) { 05564 found = 1; 05565 if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) { 05566 if (option_debug > 2) 05567 ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x); 05568 if (x == 1) 05569 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05570 } else { 05571 if (option_debug > 2) 05572 ast_log(LOG_DEBUG, "FillBitRemoval\n"); 05573 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05574 } 05575 } else if ((strncmp(a, "T38FaxTranscodingMMR", 20) == 0)) { 05576 found = 1; 05577 if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) { 05578 if (option_debug > 2) 05579 ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x); 05580 if (x == 1) 05581 peert38capability |= T38FAX_TRANSCODING_MMR; 05582 } else { 05583 if (option_debug > 2) 05584 ast_log(LOG_DEBUG, "Transcoding MMR\n"); 05585 peert38capability |= T38FAX_TRANSCODING_MMR; 05586 } 05587 } else if ((strncmp(a, "T38FaxTranscodingJBIG", 21) == 0)) { 05588 found = 1; 05589 if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) { 05590 if (option_debug > 2) 05591 ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x); 05592 if (x == 1) 05593 peert38capability |= T38FAX_TRANSCODING_JBIG; 05594 } else { 05595 if (option_debug > 2) 05596 ast_log(LOG_DEBUG, "Transcoding JBIG\n"); 05597 peert38capability |= T38FAX_TRANSCODING_JBIG; 05598 } 05599 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 05600 found = 1; 05601 if (option_debug > 2) 05602 ast_log(LOG_DEBUG, "RateManagement: %s\n", s); 05603 if (!strcasecmp(s, "localTCF")) 05604 peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 05605 else if (!strcasecmp(s, "transferredTCF")) 05606 peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 05607 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 05608 found = 1; 05609 if (option_debug > 2) 05610 ast_log(LOG_DEBUG, "UDP EC: %s\n", s); 05611 if (!strcasecmp(s, "t38UDPRedundancy")) { 05612 peert38capability |= T38FAX_UDP_EC_REDUNDANCY; 05613 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 05614 } else if (!strcasecmp(s, "t38UDPFEC")) { 05615 peert38capability |= T38FAX_UDP_EC_FEC; 05616 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 05617 } else { 05618 peert38capability |= T38FAX_UDP_EC_NONE; 05619 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05620 } 05621 } 05622 } 05623 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 05624 p->t38.peercapability = peert38capability; 05625 p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */ 05626 peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 05627 p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */ 05628 } 05629 if (debug) 05630 ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 05631 p->t38.capability, 05632 p->t38.peercapability, 05633 p->t38.jointcapability); 05634 } else { 05635 p->t38.state = T38_DISABLED; 05636 if (option_debug > 2) 05637 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05638 } 05639 05640 /* Now gather all of the codecs that we are asked for: */ 05641 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 05642 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 05643 05644 newjointcapability = p->capability & (peercapability | vpeercapability); 05645 newpeercapability = (peercapability | vpeercapability); 05646 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 05647 05648 05649 if (debug) { 05650 /* shame on whoever coded this.... */ 05651 char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE]; 05652 05653 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 05654 ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability), 05655 ast_getformatname_multiple(s2, SIPBUFSIZE, newpeercapability), 05656 ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability), 05657 ast_getformatname_multiple(s4, SIPBUFSIZE, newjointcapability)); 05658 05659 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 05660 ast_rtp_lookup_mime_multiple(s1, SIPBUFSIZE, p->noncodeccapability, 0, 0), 05661 ast_rtp_lookup_mime_multiple(s2, SIPBUFSIZE, peernoncodeccapability, 0, 0), 05662 ast_rtp_lookup_mime_multiple(s3, SIPBUFSIZE, newnoncodeccapability, 0, 0)); 05663 } 05664 if (!newjointcapability) { 05665 /* If T.38 was not negotiated either, totally bail out... */ 05666 if (!p->t38.jointcapability || !udptlportno) { 05667 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 05668 /* Do NOT Change current setting */ 05669 return -1; 05670 } else { 05671 if (option_debug > 2) 05672 ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n"); 05673 return 0; 05674 } 05675 } 05676 05677 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 05678 they are acceptable */ 05679 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 05680 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 05681 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 05682 05683 ast_rtp_pt_copy(p->rtp, newaudiortp); 05684 if (p->vrtp) 05685 ast_rtp_pt_copy(p->vrtp, newvideortp); 05686 05687 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 05688 ast_clear_flag(&p->flags[0], SIP_DTMF); 05689 if (newnoncodeccapability & AST_RTP_DTMF) { 05690 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 05691 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 05692 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 05693 ast_rtp_setdtmf(p->rtp, 1); 05694 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05695 } else { 05696 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 05697 } 05698 } 05699 05700 /* Setup audio port number */ 05701 if (p->rtp && sin.sin_port) { 05702 ast_rtp_set_peer(p->rtp, &sin); 05703 if (debug) 05704 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05705 } 05706 05707 /* Setup video port number */ 05708 if (p->vrtp && vsin.sin_port) { 05709 ast_rtp_set_peer(p->vrtp, &vsin); 05710 if (debug) 05711 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 05712 } 05713 05714 /* Ok, we're going with this offer */ 05715 if (option_debug > 1) { 05716 char buf[SIPBUFSIZE]; 05717 ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability)); 05718 } 05719 05720 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 05721 return 0; 05722 05723 if (option_debug > 3) 05724 ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n"); 05725 05726 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05727 if (debug) { 05728 char s1[SIPBUFSIZE], s2[SIPBUFSIZE]; 05729 ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 05730 ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability), 05731 ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats)); 05732 } 05733 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); 05734 ast_set_read_format(p->owner, p->owner->readformat); 05735 ast_set_write_format(p->owner, p->owner->writeformat); 05736 } 05737 05738 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 05739 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 05740 /* Activate a re-invite */ 05741 ast_queue_frame(p->owner, &ast_null_frame); 05742 } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { 05743 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 05744 S_OR(p->mohsuggest, NULL), 05745 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 05746 if (sendonly) 05747 ast_rtp_stop(p->rtp); 05748 /* RTCP needs to go ahead, even if we're on hold!!! */ 05749 /* Activate a re-invite */ 05750 ast_queue_frame(p->owner, &ast_null_frame); 05751 } 05752 05753 /* Manager Hold and Unhold events must be generated, if necessary */ 05754 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) 05755 change_hold_state(p, req, FALSE, sendonly); 05756 else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) 05757 change_hold_state(p, req, TRUE, sendonly); 05758 return 0; 05759 }
static int queue_request | ( | struct sip_pvt * | p, | |
const struct sip_request * | req | |||
) | [static] |
Definition at line 16280 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().
16281 { 16282 struct sip_request *newreq; 16283 16284 if (!(newreq = ast_calloc(1, sizeof(*newreq)))) { 16285 return -1; 16286 } 16287 16288 copy_request(newreq, req); 16289 AST_LIST_INSERT_TAIL(&p->request_queue, newreq, next); 16290 if (p->request_queue_sched_id == -1) { 16291 p->request_queue_sched_id = ast_sched_add(sched, 10, scheduler_process_request_queue, p); 16292 } 16293 16294 return 0; 16295 }
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 2546 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.
02547 { 02548 struct sip_peer *peer=NULL; 02549 struct ast_variable *var = NULL; 02550 struct ast_config *peerlist = NULL; 02551 struct ast_variable *tmp; 02552 struct ast_flags flags = {0}; 02553 const char *iabuf = NULL; 02554 char portstring[6]; /*up to five digits plus null terminator*/ 02555 const char *insecure; 02556 char *cat = NULL; 02557 unsigned short portnum; 02558 02559 /* First check on peer name */ 02560 if (newpeername) { 02561 var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL); 02562 if (!var && sin) 02563 var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02564 if (!var) { 02565 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 02566 /*!\note 02567 * If this one loaded something, then we need to ensure that the host 02568 * field matched. The only reason why we can't have this as a criteria 02569 * is because we only have the IP address and the host field might be 02570 * set as a name (and the reverse PTR might not match). 02571 */ 02572 if (var && sin) { 02573 for (tmp = var; tmp; tmp = tmp->next) { 02574 if (!strcasecmp(tmp->name, "host")) { 02575 struct hostent *hp; 02576 struct ast_hostent ahp; 02577 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02578 /* No match */ 02579 ast_variables_destroy(var); 02580 var = NULL; 02581 } 02582 break; 02583 } 02584 } 02585 } 02586 } 02587 } 02588 02589 if (!var && sin) { /* Then check on IP address */ 02590 iabuf = ast_inet_ntoa(sin->sin_addr); 02591 portnum = ntohs(sin->sin_port); 02592 sprintf(portstring, "%d", portnum); 02593 var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */ 02594 if (!var) 02595 var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL); /* Then check for registered hosts */ 02596 if (!var) { 02597 peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/ 02598 if(peerlist){ 02599 while((cat = ast_category_browse(peerlist, cat))) 02600 { 02601 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02602 set_insecure_flags(&flags, insecure, -1); 02603 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02604 var = ast_category_root(peerlist, cat); 02605 break; 02606 } 02607 } 02608 } 02609 if(!var) { 02610 ast_config_destroy(peerlist); 02611 peerlist = NULL; /*for safety's sake*/ 02612 cat = NULL; 02613 peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/ 02614 if(peerlist) { 02615 while((cat = ast_category_browse(peerlist, cat))) 02616 { 02617 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02618 set_insecure_flags(&flags, insecure, -1); 02619 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02620 var = ast_category_root(peerlist, cat); 02621 break; 02622 } 02623 } 02624 } 02625 } 02626 } 02627 } 02628 02629 if (!var) { 02630 if(peerlist) 02631 ast_config_destroy(peerlist); 02632 return NULL; 02633 } 02634 02635 for (tmp = var; tmp; tmp = tmp->next) { 02636 /* If this is type=user, then skip this object. */ 02637 if (!strcasecmp(tmp->name, "type") && 02638 !strcasecmp(tmp->value, "user")) { 02639 ast_variables_destroy(var); 02640 return NULL; 02641 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 02642 newpeername = tmp->value; 02643 } 02644 } 02645 02646 if (!newpeername) { /* Did not find peer in realtime */ 02647 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); 02648 if(peerlist) 02649 ast_config_destroy(peerlist); 02650 else 02651 ast_variables_destroy(var); 02652 return NULL; 02653 } 02654 02655 /* Peer found in realtime, now build it in memory */ 02656 peer = build_peer(newpeername, var, NULL, 1); 02657 if (!peer) { 02658 if(peerlist) 02659 ast_config_destroy(peerlist); 02660 else 02661 ast_variables_destroy(var); 02662 return NULL; 02663 } 02664 02665 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) { 02666 /* Cache peer */ 02667 ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 02668 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 02669 if (!AST_SCHED_DEL(sched, peer->expire)) { 02670 struct sip_peer *peer_ptr = peer; 02671 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02672 } 02673 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, ASTOBJ_REF(peer)); 02674 if (peer->expire == -1) { 02675 struct sip_peer *peer_ptr = peer; 02676 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02677 } 02678 } 02679 ASTOBJ_CONTAINER_LINK(&peerl,peer); 02680 } 02681 ast_set_flag(&peer->flags[0], SIP_REALTIME); 02682 if(peerlist) 02683 ast_config_destroy(peerlist); 02684 else 02685 ast_variables_destroy(var); 02686 return peer; 02687 }
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 2427 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.
02428 { 02429 char port[10]; 02430 char ipaddr[INET_ADDRSTRLEN]; 02431 char regseconds[20]; 02432 char str_lastms[20]; 02433 02434 char *sysname = ast_config_AST_SYSTEM_NAME; 02435 char *syslabel = NULL; 02436 02437 time_t nowtime = time(NULL) + expirey; 02438 const char *fc = fullcontact ? "fullcontact" : NULL; 02439 02440 snprintf(str_lastms, sizeof(str_lastms), "%d", lastms); 02441 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 02442 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 02443 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02444 02445 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 02446 sysname = NULL; 02447 else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME)) 02448 syslabel = "regserver"; 02449 02450 if (fc) 02451 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02452 "port", port, "regseconds", regseconds, 02453 "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */ 02454 else 02455 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02456 "port", port, "regseconds", regseconds, 02457 "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */ 02458 /* We cannot do this in the same statement as above, because the lack of 02459 * this field could cause the whole statement to fail. */ 02460 ast_update_realtime("sippeers", "name", peername, "lastms", str_lastms, NULL); 02461 }
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 2737 of file chan_sip.c.
References ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, ast_variable::value, and var.
02738 { 02739 struct ast_variable *var; 02740 struct ast_variable *tmp; 02741 struct sip_user *user = NULL; 02742 02743 var = ast_load_realtime("sipusers", "name", username, NULL); 02744 02745 if (!var) 02746 return NULL; 02747 02748 for (tmp = var; tmp; tmp = tmp->next) { 02749 if (!strcasecmp(tmp->name, "type") && 02750 !strcasecmp(tmp->value, "peer")) { 02751 ast_variables_destroy(var); 02752 return NULL; 02753 } 02754 } 02755 02756 user = build_user(username, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02757 02758 if (!user) { /* No user found */ 02759 ast_variables_destroy(var); 02760 return NULL; 02761 } 02762 02763 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02764 ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02765 suserobjs++; 02766 ASTOBJ_CONTAINER_LINK(&userl,user); 02767 } else { 02768 /* Move counter from s to r... */ 02769 suserobjs--; 02770 ruserobjs++; 02771 } 02772 ast_set_flag(&user->flags[0], SIP_REALTIME); 02773 ast_variables_destroy(var); 02774 return user; 02775 }
static void receive_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 10114 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().
10115 { 10116 char buf[1024]; 10117 struct ast_frame f; 10118 const char *content_type = get_header(req, "Content-Type"); 10119 10120 if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */ 10121 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 10122 if (!p->owner) 10123 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10124 return; 10125 } 10126 10127 if (get_msg_text(buf, sizeof(buf), req)) { 10128 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 10129 transmit_response(p, "202 Accepted", req); 10130 if (!p->owner) 10131 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10132 return; 10133 } 10134 10135 if (p->owner) { 10136 if (sip_debug_test_pvt(p)) 10137 ast_verbose("Message received: '%s'\n", buf); 10138 memset(&f, 0, sizeof(f)); 10139 f.frametype = AST_FRAME_TEXT; 10140 f.subclass = 0; 10141 f.offset = 0; 10142 f.data = buf; 10143 f.datalen = strlen(buf); 10144 ast_queue_frame(p->owner, &f); 10145 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 10146 } else { /* Message outside of a call, we do not support that */ 10147 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); 10148 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 10149 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10150 } 10151 return; 10152 }
static char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 1646 of file chan_sip.c.
References referstatusstrings, and text.
Referenced by __sip_show_channels().
01647 { 01648 int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0])); 01649 int x; 01650 01651 for (x = 0; x < i; x++) { 01652 if (referstatusstrings[x].status == rstatus) 01653 return (char *) referstatusstrings[x].text; 01654 } 01655 return ""; 01656 }
static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 8213 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.
08214 { 08215 char data[256]; 08216 struct in_addr in; 08217 int expiry; 08218 int port; 08219 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 08220 08221 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08222 return; 08223 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 08224 return; 08225 08226 scan = data; 08227 addr = strsep(&scan, ":"); 08228 port_str = strsep(&scan, ":"); 08229 expiry_str = strsep(&scan, ":"); 08230 username = strsep(&scan, ":"); 08231 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 08232 08233 if (!inet_aton(addr, &in)) 08234 return; 08235 08236 if (port_str) 08237 port = atoi(port_str); 08238 else 08239 return; 08240 08241 if (expiry_str) 08242 expiry = atoi(expiry_str); 08243 else 08244 return; 08245 08246 if (username) 08247 ast_copy_string(peer->username, username, sizeof(peer->username)); 08248 if (contact) 08249 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 08250 08251 if (option_debug > 1) 08252 ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 08253 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 08254 08255 memset(&peer->addr, 0, sizeof(peer->addr)); 08256 peer->addr.sin_family = AF_INET; 08257 peer->addr.sin_addr = in; 08258 peer->addr.sin_port = htons(port); 08259 if (sipsock < 0) { 08260 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 08261 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 08262 struct sip_peer *peer_ptr = peer; 08263 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08264 } 08265 peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, ASTOBJ_REF(peer)); 08266 if (peer->pokeexpire == -1) { 08267 struct sip_peer *peer_ptr = peer; 08268 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08269 } 08270 } else 08271 sip_poke_peer(peer); 08272 if (!AST_SCHED_DEL(sched, peer->expire)) { 08273 struct sip_peer *peer_ptr = peer; 08274 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08275 } 08276 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08277 if (peer->expire == -1) { 08278 struct sip_peer *peer_ptr = peer; 08279 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08280 } 08281 register_peer_exten(peer, TRUE); 08282 }
static void register_peer_exten | ( | struct sip_peer * | peer, | |
int | onoff | |||
) | [static] |
Automatically add peer extension to dial plan.
Definition at line 2464 of file chan_sip.c.
References ast_add_extension(), ast_context_find(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free, ast_log(), ast_strdup, ast_strlen_zero(), context, ext, LOG_WARNING, sip_peer::name, sip_peer::regexten, and S_OR.
02465 { 02466 char multi[256]; 02467 char *stringp, *ext, *context; 02468 02469 /* XXX note that global_regcontext is both a global 'enable' flag and 02470 * the name of the global regexten context, if not specified 02471 * individually. 02472 */ 02473 if (ast_strlen_zero(global_regcontext)) 02474 return; 02475 02476 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 02477 stringp = multi; 02478 while ((ext = strsep(&stringp, "&"))) { 02479 if ((context = strchr(ext, '@'))) { 02480 *context++ = '\0'; /* split ext@context */ 02481 if (!ast_context_find(context)) { 02482 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 02483 continue; 02484 } 02485 } else { 02486 context = global_regcontext; 02487 } 02488 if (onoff) { 02489 if (!ast_exists_extension(NULL, context, ext, 1, NULL)) { 02490 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 02491 ast_strdup(peer->name), ast_free, "SIP"); 02492 } 02493 } else { 02494 ast_context_remove_extension(context, ext, 1, NULL); 02495 } 02496 } 02497 }
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 9015 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.
09017 { 09018 enum check_auth_result res = AUTH_NOT_FOUND; 09019 struct sip_peer *peer; 09020 char tmp[256]; 09021 char *name, *c; 09022 char *t; 09023 char *domain; 09024 09025 /* Terminate URI */ 09026 t = uri; 09027 while(*t && (*t > 32) && (*t != ';')) 09028 t++; 09029 *t = '\0'; 09030 09031 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 09032 if (pedanticsipchecking) 09033 ast_uri_decode(tmp); 09034 09035 c = get_in_brackets(tmp); 09036 c = strsep(&c, ";"); /* Ditch ;user=phone */ 09037 09038 if (!strncasecmp(c, "sip:", 4)) { 09039 name = c + 4; 09040 } else { 09041 name = c; 09042 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 09043 } 09044 09045 /* Strip off the domain name */ 09046 if ((c = strchr(name, '@'))) { 09047 *c++ = '\0'; 09048 domain = c; 09049 if ((c = strchr(domain, ':'))) /* Remove :port */ 09050 *c = '\0'; 09051 if (!AST_LIST_EMPTY(&domain_list)) { 09052 if (!check_sip_domain(domain, NULL, 0)) { 09053 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 09054 return AUTH_UNKNOWN_DOMAIN; 09055 } 09056 } 09057 } 09058 09059 ast_string_field_set(p, exten, name); 09060 build_contact(p); 09061 peer = find_peer(name, NULL, 1, 0); 09062 if (!(peer && ast_apply_ha(peer->ha, sin))) { 09063 /* Peer fails ACL check */ 09064 if (peer) { 09065 ASTOBJ_UNREF(peer, sip_destroy_peer); 09066 res = AUTH_ACL_FAILED; 09067 } else 09068 res = AUTH_NOT_FOUND; 09069 } 09070 if (peer) { 09071 /* Set Frame packetization */ 09072 if (p->rtp) { 09073 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09074 p->autoframing = peer->autoframing; 09075 } 09076 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 09077 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 09078 res = AUTH_PEER_NOT_DYNAMIC; 09079 } else { 09080 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 09081 transmit_response(p, "100 Trying", req); 09082 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09083 if (sip_cancel_destroy(p)) 09084 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09085 09086 /* We have a succesful registration attemp with proper authentication, 09087 now, update the peer */ 09088 switch (parse_register_contact(p, peer, req)) { 09089 case PARSE_REGISTER_FAILED: 09090 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 09091 transmit_response_with_date(p, "400 Bad Request", req); 09092 peer->lastmsgssent = -1; 09093 res = 0; 09094 break; 09095 case PARSE_REGISTER_QUERY: 09096 transmit_response_with_date(p, "200 OK", req); 09097 peer->lastmsgssent = -1; 09098 res = 0; 09099 break; 09100 case PARSE_REGISTER_UPDATE: 09101 update_peer(peer, p->expiry); 09102 /* Say OK and ask subsystem to retransmit msg counter */ 09103 transmit_response_with_date(p, "200 OK", req); 09104 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 09105 peer->lastmsgssent = -1; 09106 res = 0; 09107 break; 09108 } 09109 } 09110 } 09111 } 09112 if (!peer && autocreatepeer) { 09113 /* Create peer if we have autocreate mode enabled */ 09114 peer = temp_peer(name); 09115 if (peer) { 09116 ASTOBJ_CONTAINER_LINK(&peerl, peer); 09117 if (sip_cancel_destroy(p)) 09118 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09119 switch (parse_register_contact(p, peer, req)) { 09120 case PARSE_REGISTER_FAILED: 09121 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 09122 transmit_response_with_date(p, "400 Bad Request", req); 09123 peer->lastmsgssent = -1; 09124 res = 0; 09125 break; 09126 case PARSE_REGISTER_QUERY: 09127 transmit_response_with_date(p, "200 OK", req); 09128 peer->lastmsgssent = -1; 09129 res = 0; 09130 break; 09131 case PARSE_REGISTER_UPDATE: 09132 /* Say OK and ask subsystem to retransmit msg counter */ 09133 transmit_response_with_date(p, "200 OK", req); 09134 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 09135 peer->lastmsgssent = -1; 09136 res = 0; 09137 break; 09138 } 09139 } 09140 } 09141 if (!peer && global_alwaysauthreject) { 09142 /* If we found a peer, we transmit a 100 Trying. Therefore, if we're 09143 * trying to avoid leaking information, we MUST also transmit the same 09144 * response when we DON'T find a peer. */ 09145 transmit_response(p, "100 Trying", req); 09146 /* Insert a fake delay between the 100 and the subsequent failure. */ 09147 sched_yield(); 09148 } 09149 if (!res) { 09150 ast_device_state_changed("SIP/%s", peer->name); 09151 } 09152 if (res < 0) { 09153 switch (res) { 09154 case AUTH_SECRET_FAILED: 09155 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 09156 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 09157 break; 09158 case AUTH_USERNAME_MISMATCH: 09159 /* Username and digest username does not match. 09160 Asterisk uses the From: username for authentication. We need the 09161 users to use the same authentication user name until we support 09162 proper authentication by digest auth name */ 09163 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 09164 break; 09165 case AUTH_NOT_FOUND: 09166 case AUTH_PEER_NOT_DYNAMIC: 09167 case AUTH_ACL_FAILED: 09168 if (global_alwaysauthreject) { 09169 transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE); 09170 } else { 09171 /* URI not found */ 09172 if (res == AUTH_PEER_NOT_DYNAMIC) 09173 transmit_response(p, "403 Forbidden", &p->initreq); 09174 else 09175 transmit_response(p, "404 Not found", &p->initreq); 09176 } 09177 break; 09178 default: 09179 break; 09180 } 09181 } 09182 if (peer) 09183 ASTOBJ_UNREF(peer, sip_destroy_peer); 09184 09185 return res; 09186 }
static char * regstate2str | ( | enum sipregistrystate | regstate | ) | const [static] |
Convert registration state status to string.
Definition at line 7683 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.
07684 { 07685 switch(regstate) { 07686 case REG_STATE_FAILED: 07687 return "Failed"; 07688 case REG_STATE_UNREGISTERED: 07689 return "Unregistered"; 07690 case REG_STATE_REGSENT: 07691 return "Request Sent"; 07692 case REG_STATE_AUTHSENT: 07693 return "Auth. Sent"; 07694 case REG_STATE_REGISTERED: 07695 return "Registered"; 07696 case REG_STATE_REJECTED: 07697 return "Rejected"; 07698 case REG_STATE_TIMEOUT: 07699 return "Timeout"; 07700 case REG_STATE_NOAUTH: 07701 return "No Authentication"; 07702 default: 07703 return "Unknown"; 07704 } 07705 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 18918 of file chan_sip.c.
References sip_reload().
18919 { 18920 return sip_reload(0, 0, NULL); 18921 }
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 17797 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().
17798 { 17799 struct ast_config *cfg, *ucfg; 17800 struct ast_variable *v; 17801 struct sip_peer *peer; 17802 struct sip_user *user; 17803 struct ast_hostent ahp; 17804 char *cat, *stringp, *context, *oldregcontext; 17805 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 17806 struct hostent *hp; 17807 int format; 17808 struct ast_flags dummy[2]; 17809 int auto_sip_domains = FALSE; 17810 struct sockaddr_in old_bindaddr = bindaddr; 17811 int registry_count = 0, peer_count = 0, user_count = 0; 17812 unsigned int temp_tos = 0; 17813 struct ast_flags debugflag = {0}; 17814 17815 cfg = ast_config_load(config); 17816 17817 /* We *must* have a config file otherwise stop immediately */ 17818 if (!cfg) { 17819 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 17820 return -1; 17821 } 17822 17823 if (option_debug > 3) 17824 ast_log(LOG_DEBUG, "--------------- SIP reload started\n"); 17825 17826 clear_realm_authentication(authl); 17827 clear_sip_domains(); 17828 authl = NULL; 17829 17830 ast_free_ha(global_contact_ha); 17831 global_contact_ha = NULL; 17832 17833 /* First, destroy all outstanding registry calls */ 17834 /* This is needed, since otherwise active registry entries will not be destroyed */ 17835 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17836 ASTOBJ_RDLOCK(iterator); 17837 if (iterator->call) { 17838 if (option_debug > 2) 17839 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 17840 /* This will also remove references to the registry */ 17841 sip_destroy(iterator->call); 17842 } 17843 ASTOBJ_UNLOCK(iterator); 17844 17845 } while(0)); 17846 17847 /* Then, actually destroy users and registry */ 17848 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 17849 if (option_debug > 3) 17850 ast_log(LOG_DEBUG, "--------------- Done destroying user list\n"); 17851 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 17852 if (option_debug > 3) 17853 ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n"); 17854 ASTOBJ_CONTAINER_MARKALL(&peerl); 17855 17856 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 17857 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 17858 oldregcontext = oldcontexts; 17859 17860 /* Clear all flags before setting default values */ 17861 /* Preserve debugging settings for console */ 17862 ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 17863 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 17864 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 17865 ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE); 17866 17867 /* Reset IP addresses */ 17868 memset(&bindaddr, 0, sizeof(bindaddr)); 17869 ast_free_ha(localaddr); 17870 memset(&localaddr, 0, sizeof(localaddr)); 17871 memset(&externip, 0, sizeof(externip)); 17872 memset(&default_prefs, 0 , sizeof(default_prefs)); 17873 outboundproxyip.sin_port = htons(STANDARD_SIP_PORT); 17874 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 17875 ourport = STANDARD_SIP_PORT; 17876 srvlookup = DEFAULT_SRVLOOKUP; 17877 global_tos_sip = DEFAULT_TOS_SIP; 17878 global_tos_audio = DEFAULT_TOS_AUDIO; 17879 global_tos_video = DEFAULT_TOS_VIDEO; 17880 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 17881 externexpire = 0; /* Expiration for DNS re-issuing */ 17882 externrefresh = 10; 17883 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 17884 17885 /* Reset channel settings to default before re-configuring */ 17886 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 17887 global_regcontext[0] = '\0'; 17888 expiry = DEFAULT_EXPIRY; 17889 global_notifyringing = DEFAULT_NOTIFYRINGING; 17890 global_limitonpeers = FALSE; 17891 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 17892 global_notifyhold = FALSE; 17893 global_alwaysauthreject = 0; 17894 global_allowsubscribe = FALSE; 17895 ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent)); 17896 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 17897 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) 17898 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 17899 else 17900 ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm)); 17901 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 17902 compactheaders = DEFAULT_COMPACTHEADERS; 17903 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 17904 global_regattempts_max = 0; 17905 pedanticsipchecking = DEFAULT_PEDANTIC; 17906 global_mwitime = DEFAULT_MWITIME; 17907 autocreatepeer = DEFAULT_AUTOCREATEPEER; 17908 global_autoframing = 0; 17909 global_allowguest = DEFAULT_ALLOWGUEST; 17910 global_rtptimeout = 0; 17911 global_rtpholdtimeout = 0; 17912 global_rtpkeepalive = 0; 17913 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 17914 global_rtautoclear = 120; 17915 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 17916 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 17917 ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE); 17918 17919 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 17920 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 17921 default_subscribecontext[0] = '\0'; 17922 default_language[0] = '\0'; 17923 default_fromdomain[0] = '\0'; 17924 default_qualify = DEFAULT_QUALIFY; 17925 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 17926 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 17927 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 17928 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 17929 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 17930 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 17931 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 17932 17933 /* Debugging settings, always default to off */ 17934 dumphistory = FALSE; 17935 recordhistory = FALSE; 17936 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 17937 17938 /* Misc settings for the channel */ 17939 global_relaxdtmf = FALSE; 17940 global_callevents = FALSE; 17941 global_t1min = DEFAULT_T1MIN; 17942 17943 global_matchexterniplocally = FALSE; 17944 17945 /* Copy the default jb config over global_jbconf */ 17946 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 17947 17948 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 17949 17950 /* Read the [general] config section of sip.conf (or from realtime config) */ 17951 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 17952 if (handle_common_options(&global_flags[0], &dummy[0], v)) 17953 continue; 17954 /* handle jb conf */ 17955 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 17956 continue; 17957 17958 /* Create the interface list */ 17959 if (!strcasecmp(v->name, "context")) { 17960 ast_copy_string(default_context, v->value, sizeof(default_context)); 17961 } else if (!strcasecmp(v->name, "subscribecontext")) { 17962 ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext)); 17963 } else if (!strcasecmp(v->name, "allowguest")) { 17964 global_allowguest = ast_true(v->value) ? 1 : 0; 17965 } else if (!strcasecmp(v->name, "realm")) { 17966 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 17967 } else if (!strcasecmp(v->name, "useragent")) { 17968 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 17969 if (option_debug) 17970 ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 17971 } else if (!strcasecmp(v->name, "allowtransfer")) { 17972 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17973 } else if (!strcasecmp(v->name, "rtcachefriends")) { 17974 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 17975 } else if (!strcasecmp(v->name, "rtsavesysname")) { 17976 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME); 17977 } else if (!strcasecmp(v->name, "rtupdate")) { 17978 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE); 17979 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 17980 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 17981 } else if (!strcasecmp(v->name, "t1min")) { 17982 global_t1min = atoi(v->value); 17983 } else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) { 17984 global_dynamic_exclude_static = ast_true(v->value); 17985 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 17986 global_contact_ha = ast_append_ha(v->name + 7, v->value, global_contact_ha); 17987 } else if (!strcasecmp(v->name, "rtautoclear")) { 17988 int i = atoi(v->value); 17989 if (i > 0) 17990 global_rtautoclear = i; 17991 else 17992 i = 0; 17993 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 17994 } else if (!strcasecmp(v->name, "usereqphone")) { 17995 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 17996 } else if (!strcasecmp(v->name, "relaxdtmf")) { 17997 global_relaxdtmf = ast_true(v->value); 17998 } else if (!strcasecmp(v->name, "checkmwi")) { 17999 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 18000 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 18001 global_mwitime = DEFAULT_MWITIME; 18002 } 18003 } else if (!strcasecmp(v->name, "vmexten")) { 18004 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 18005 } else if (!strcasecmp(v->name, "rtptimeout")) { 18006 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 18007 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 18008 global_rtptimeout = 0; 18009 } 18010 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 18011 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 18012 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 18013 global_rtpholdtimeout = 0; 18014 } 18015 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 18016 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 18017 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 18018 global_rtpkeepalive = 0; 18019 } 18020 } else if (!strcasecmp(v->name, "compactheaders")) { 18021 compactheaders = ast_true(v->value); 18022 } else if (!strcasecmp(v->name, "notifymimetype")) { 18023 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 18024 } else if (!strncasecmp(v->name, "limitonpeer", 11)) { 18025 global_limitonpeers = ast_true(v->value); 18026 } else if (!strcasecmp(v->name, "directrtpsetup")) { 18027 global_directrtpsetup = ast_true(v->value); 18028 } else if (!strcasecmp(v->name, "notifyringing")) { 18029 global_notifyringing = ast_true(v->value); 18030 } else if (!strcasecmp(v->name, "notifyhold")) { 18031 global_notifyhold = ast_true(v->value); 18032 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 18033 global_alwaysauthreject = ast_true(v->value); 18034 } else if (!strcasecmp(v->name, "mohinterpret") 18035 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 18036 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 18037 } else if (!strcasecmp(v->name, "mohsuggest")) { 18038 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 18039 } else if (!strcasecmp(v->name, "language")) { 18040 ast_copy_string(default_language, v->value, sizeof(default_language)); 18041 } else if (!strcasecmp(v->name, "regcontext")) { 18042 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 18043 stringp = newcontexts; 18044 /* Let's remove any contexts that are no longer defined in regcontext */ 18045 cleanup_stale_contexts(stringp, oldregcontext); 18046 /* Create contexts if they don't exist already */ 18047 while ((context = strsep(&stringp, "&"))) { 18048 if (!ast_context_find(context)) 18049 ast_context_create(NULL, context,"SIP"); 18050 } 18051 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 18052 } else if (!strcasecmp(v->name, "callerid")) { 18053 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 18054 } else if (!strcasecmp(v->name, "fromdomain")) { 18055 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 18056 } else if (!strcasecmp(v->name, "outboundproxy")) { 18057 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 18058 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 18059 } else if (!strcasecmp(v->name, "outboundproxyport")) { 18060 /* Port needs to be after IP */ 18061 sscanf(v->value, "%d", &format); 18062 outboundproxyip.sin_port = htons(format); 18063 } else if (!strcasecmp(v->name, "autocreatepeer")) { 18064 autocreatepeer = ast_true(v->value); 18065 } else if (!strcasecmp(v->name, "srvlookup")) { 18066 srvlookup = ast_true(v->value); 18067 } else if (!strcasecmp(v->name, "pedantic")) { 18068 pedanticsipchecking = ast_true(v->value); 18069 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 18070 max_expiry = atoi(v->value); 18071 if (max_expiry < 1) 18072 max_expiry = DEFAULT_MAX_EXPIRY; 18073 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 18074 min_expiry = atoi(v->value); 18075 if (min_expiry < 1) 18076 min_expiry = DEFAULT_MIN_EXPIRY; 18077 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 18078 default_expiry = atoi(v->value); 18079 if (default_expiry < 1) 18080 default_expiry = DEFAULT_DEFAULT_EXPIRY; 18081 } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */ 18082 if (ast_true(v->value)) 18083 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 18084 } else if (!strcasecmp(v->name, "dumphistory")) { 18085 dumphistory = ast_true(v->value); 18086 } else if (!strcasecmp(v->name, "recordhistory")) { 18087 recordhistory = ast_true(v->value); 18088 } else if (!strcasecmp(v->name, "registertimeout")) { 18089 global_reg_timeout = atoi(v->value); 18090 if (global_reg_timeout < 1) 18091 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 18092 } else if (!strcasecmp(v->name, "registerattempts")) { 18093 global_regattempts_max = atoi(v->value); 18094 } else if (!strcasecmp(v->name, "bindaddr")) { 18095 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 18096 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 18097 } else { 18098 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 18099 } 18100 } else if (!strcasecmp(v->name, "localnet")) { 18101 struct ast_ha *na; 18102 if (!(na = ast_append_ha("d", v->value, localaddr))) 18103 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 18104 else 18105 localaddr = na; 18106 } else if (!strcasecmp(v->name, "localmask")) { 18107 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 18108 } else if (!strcasecmp(v->name, "externip")) { 18109 if (!(hp = ast_gethostbyname(v->value, &ahp))) 18110 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 18111 else 18112 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 18113 externexpire = 0; 18114 } else if (!strcasecmp(v->name, "externhost")) { 18115 ast_copy_string(externhost, v->value, sizeof(externhost)); 18116 if (!(hp = ast_gethostbyname(externhost, &ahp))) 18117 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 18118 else 18119 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 18120 externexpire = time(NULL); 18121 } else if (!strcasecmp(v->name, "externrefresh")) { 18122 if (sscanf(v->value, "%d", &externrefresh) != 1) { 18123 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 18124 externrefresh = 10; 18125 } 18126 } else if (!strcasecmp(v->name, "allow")) { 18127 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1); 18128 } else if (!strcasecmp(v->name, "disallow")) { 18129 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0); 18130 } else if (!strcasecmp(v->name, "autoframing")) { 18131 global_autoframing = ast_true(v->value); 18132 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 18133 allow_external_domains = ast_true(v->value); 18134 } else if (!strcasecmp(v->name, "autodomain")) { 18135 auto_sip_domains = ast_true(v->value); 18136 } else if (!strcasecmp(v->name, "domain")) { 18137 char *domain = ast_strdupa(v->value); 18138 char *context = strchr(domain, ','); 18139 18140 if (context) 18141 *context++ = '\0'; 18142 18143 if (option_debug && ast_strlen_zero(context)) 18144 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 18145 if (ast_strlen_zero(domain)) 18146 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 18147 else 18148 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 18149 } else if (!strcasecmp(v->name, "register")) { 18150 if (sip_register(v->value, v->lineno) == 0) 18151 registry_count++; 18152 } else if (!strcasecmp(v->name, "tos")) { 18153 if (!ast_str2tos(v->value, &temp_tos)) { 18154 global_tos_sip = temp_tos; 18155 global_tos_audio = temp_tos; 18156 global_tos_video = temp_tos; 18157 ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno); 18158 } else 18159 ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno); 18160 } else if (!strcasecmp(v->name, "tos_sip")) { 18161 if (ast_str2tos(v->value, &global_tos_sip)) 18162 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); 18163 } else if (!strcasecmp(v->name, "tos_audio")) { 18164 if (ast_str2tos(v->value, &global_tos_audio)) 18165 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); 18166 } else if (!strcasecmp(v->name, "tos_video")) { 18167 if (ast_str2tos(v->value, &global_tos_video)) 18168 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); 18169 } else if (!strcasecmp(v->name, "bindport")) { 18170 if (sscanf(v->value, "%d", &ourport) == 1) { 18171 bindaddr.sin_port = htons(ourport); 18172 } else { 18173 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 18174 } 18175 } else if (!strcasecmp(v->name, "qualify")) { 18176 if (!strcasecmp(v->value, "no")) { 18177 default_qualify = 0; 18178 } else if (!strcasecmp(v->value, "yes")) { 18179 default_qualify = DEFAULT_MAXMS; 18180 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 18181 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 18182 default_qualify = 0; 18183 } 18184 } else if (!strcasecmp(v->name, "callevents")) { 18185 global_callevents = ast_true(v->value); 18186 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 18187 default_maxcallbitrate = atoi(v->value); 18188 if (default_maxcallbitrate < 0) 18189 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 18190 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 18191 global_matchexterniplocally = ast_true(v->value); 18192 } 18193 } 18194 18195 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 18196 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 18197 allow_external_domains = 1; 18198 } 18199 18200 /* Build list of authentication to various SIP realms, i.e. service providers */ 18201 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 18202 /* Format for authentication is auth = username:password@realm */ 18203 if (!strcasecmp(v->name, "auth")) 18204 authl = add_realm_authentication(authl, v->value, v->lineno); 18205 } 18206 18207 ucfg = ast_config_load("users.conf"); 18208 if (ucfg) { 18209 struct ast_variable *gen; 18210 int genhassip, genregistersip; 18211 const char *hassip, *registersip; 18212 18213 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 18214 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 18215 gen = ast_variable_browse(ucfg, "general"); 18216 cat = ast_category_browse(ucfg, NULL); 18217 while (cat) { 18218 if (strcasecmp(cat, "general")) { 18219 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 18220 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 18221 if (ast_true(hassip) || (!hassip && genhassip)) { 18222 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 18223 if (user) { 18224 ASTOBJ_CONTAINER_LINK(&userl,user); 18225 ASTOBJ_UNREF(user, sip_destroy_user); 18226 user_count++; 18227 } 18228 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 18229 if (peer) { 18230 ast_device_state_changed("SIP/%s", peer->name); 18231 ASTOBJ_CONTAINER_LINK(&peerl,peer); 18232 ASTOBJ_UNREF(peer, sip_destroy_peer); 18233 peer_count++; 18234 } 18235 } 18236 if (ast_true(registersip) || (!registersip && genregistersip)) { 18237 char tmp[256]; 18238 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 18239 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 18240 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 18241 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 18242 if (!host) 18243 host = ast_variable_retrieve(ucfg, "general", "host"); 18244 if (!username) 18245 username = ast_variable_retrieve(ucfg, "general", "username"); 18246 if (!secret) 18247 secret = ast_variable_retrieve(ucfg, "general", "secret"); 18248 if (!contact) 18249 contact = "s"; 18250 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 18251 if (!ast_strlen_zero(secret)) 18252 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 18253 else 18254 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 18255 if (sip_register(tmp, 0) == 0) 18256 registry_count++; 18257 } 18258 } 18259 } 18260 cat = ast_category_browse(ucfg, cat); 18261 } 18262 ast_config_destroy(ucfg); 18263 } 18264 18265 18266 /* Load peers, users and friends */ 18267 cat = NULL; 18268 while ( (cat = ast_category_browse(cfg, cat)) ) { 18269 const char *utype; 18270 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 18271 continue; 18272 utype = ast_variable_retrieve(cfg, cat, "type"); 18273 if (!utype) { 18274 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 18275 continue; 18276 } else { 18277 int is_user = 0, is_peer = 0; 18278 if (!strcasecmp(utype, "user")) 18279 is_user = 1; 18280 else if (!strcasecmp(utype, "friend")) 18281 is_user = is_peer = 1; 18282 else if (!strcasecmp(utype, "peer")) 18283 is_peer = 1; 18284 else { 18285 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 18286 continue; 18287 } 18288 if (is_user) { 18289 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 18290 if (user) { 18291 ASTOBJ_CONTAINER_LINK(&userl,user); 18292 ASTOBJ_UNREF(user, sip_destroy_user); 18293 user_count++; 18294 } 18295 } 18296 if (is_peer) { 18297 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 18298 if (peer) { 18299 ASTOBJ_CONTAINER_LINK(&peerl,peer); 18300 ASTOBJ_UNREF(peer, sip_destroy_peer); 18301 peer_count++; 18302 } 18303 } 18304 } 18305 } 18306 if (ast_find_ourip(&__ourip, bindaddr)) { 18307 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 18308 ast_config_destroy(cfg); 18309 return 0; 18310 } 18311 if (!ntohs(bindaddr.sin_port)) 18312 bindaddr.sin_port = ntohs(STANDARD_SIP_PORT); 18313 bindaddr.sin_family = AF_INET; 18314 ast_mutex_lock(&netlock); 18315 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 18316 close(sipsock); 18317 sipsock = -1; 18318 } 18319 if (sipsock < 0) { 18320 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 18321 if (sipsock < 0) { 18322 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 18323 ast_config_destroy(cfg); 18324 return -1; 18325 } else { 18326 /* Allow SIP clients on the same host to access us: */ 18327 const int reuseFlag = 1; 18328 18329 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 18330 (const char*)&reuseFlag, 18331 sizeof reuseFlag); 18332 18333 ast_enable_packet_fragmentation(sipsock); 18334 18335 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 18336 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 18337 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 18338 strerror(errno)); 18339 close(sipsock); 18340 sipsock = -1; 18341 } else { 18342 if (option_verbose > 1) { 18343 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 18344 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 18345 ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip)); 18346 } 18347 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 18348 ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip)); 18349 } 18350 } 18351 } 18352 ast_mutex_unlock(&netlock); 18353 18354 /* Add default domains - host name, IP address and IP:port */ 18355 /* Only do this if user added any sip domain with "localdomains" */ 18356 /* In order to *not* break backwards compatibility */ 18357 /* Some phones address us at IP only, some with additional port number */ 18358 if (auto_sip_domains) { 18359 char temp[MAXHOSTNAMELEN]; 18360 18361 /* First our default IP address */ 18362 if (bindaddr.sin_addr.s_addr) 18363 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 18364 else 18365 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 18366 18367 /* Our extern IP address, if configured */ 18368 if (externip.sin_addr.s_addr) 18369 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 18370 18371 /* Extern host name (NAT traversal support) */ 18372 if (!ast_strlen_zero(externhost)) 18373 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 18374 18375 /* Our host name */ 18376 if (!gethostname(temp, sizeof(temp))) 18377 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 18378 } 18379 18380 /* Release configuration from memory */ 18381 ast_config_destroy(cfg); 18382 18383 /* Load the list of manual NOTIFY types to support */ 18384 if (notify_types) 18385 ast_config_destroy(notify_types); 18386 notify_types = ast_config_load(notify_config); 18387 18388 /* Done, tell the manager */ 18389 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); 18390 18391 return 0; 18392 }
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 11915 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().
11916 { 11917 char tmp[512]; 11918 char *c; 11919 char oldnonce[256]; 11920 11921 /* table of recognised keywords, and places where they should be copied */ 11922 const struct x { 11923 const char *key; 11924 int field_index; 11925 } *i, keys[] = { 11926 { "realm=", ast_string_field_index(p, realm) }, 11927 { "nonce=", ast_string_field_index(p, nonce) }, 11928 { "opaque=", ast_string_field_index(p, opaque) }, 11929 { "qop=", ast_string_field_index(p, qop) }, 11930 { "domain=", ast_string_field_index(p, domain) }, 11931 { NULL, 0 }, 11932 }; 11933 11934 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 11935 if (ast_strlen_zero(tmp)) 11936 return -1; 11937 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 11938 ast_log(LOG_WARNING, "missing Digest.\n"); 11939 return -1; 11940 } 11941 c = tmp + strlen("Digest "); 11942 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 11943 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 11944 for (i = keys; i->key != NULL; i++) { 11945 char *src, *separator; 11946 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 11947 continue; 11948 /* Found. Skip keyword, take text in quotes or up to the separator. */ 11949 c += strlen(i->key); 11950 if (*c == '"') { 11951 src = ++c; 11952 separator = "\""; 11953 } else { 11954 src = c; 11955 separator = ","; 11956 } 11957 strsep(&c, separator); /* clear separator and move ptr */ 11958 ast_string_field_index_set(p, i->field_index, src); 11959 break; 11960 } 11961 if (i->key == NULL) /* not found, try ',' */ 11962 strsep(&c, ","); 11963 } 11964 /* Reset nonce count */ 11965 if (strcmp(p->nonce, oldnonce)) 11966 p->noncecount = 0; 11967 11968 /* Save auth data for following registrations */ 11969 if (p->registry) { 11970 struct sip_registry *r = p->registry; 11971 11972 if (strcmp(r->nonce, p->nonce)) { 11973 ast_string_field_set(r, realm, p->realm); 11974 ast_string_field_set(r, nonce, p->nonce); 11975 ast_string_field_set(r, domain, p->domain); 11976 ast_string_field_set(r, opaque, p->opaque); 11977 ast_string_field_set(r, qop, p->qop); 11978 r->noncecount = 0; 11979 } 11980 } 11981 return build_reply_digest(p, sipmethod, digest, digest_len); 11982 }
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 6159 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.
06160 { 06161 struct sip_request *orig = &p->initreq; 06162 char stripped[80]; 06163 char tmp[80]; 06164 char newto[256]; 06165 const char *c; 06166 const char *ot, *of; 06167 int is_strict = FALSE; /*!< Strict routing flag */ 06168 06169 memset(req, 0, sizeof(struct sip_request)); 06170 06171 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 06172 06173 if (!seqno) { 06174 p->ocseq++; 06175 seqno = p->ocseq; 06176 } 06177 06178 if (sipmethod == SIP_CANCEL) { 06179 p->branch = p->invite_branch; 06180 build_via(p); 06181 } else if (newbranch) { 06182 p->branch ^= ast_random(); 06183 build_via(p); 06184 } 06185 06186 /* Check for strict or loose router */ 06187 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) { 06188 is_strict = TRUE; 06189 if (sipdebug) 06190 ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid); 06191 } 06192 06193 if (sipmethod == SIP_CANCEL) 06194 c = p->initreq.rlPart2; /* Use original URI */ 06195 else if (sipmethod == SIP_ACK) { 06196 /* Use URI from Contact: in 200 OK (if INVITE) 06197 (we only have the contacturi on INVITEs) */ 06198 if (!ast_strlen_zero(p->okcontacturi)) 06199 c = is_strict ? p->route->hop : p->okcontacturi; 06200 else 06201 c = p->initreq.rlPart2; 06202 } else if (!ast_strlen_zero(p->okcontacturi)) 06203 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 06204 else if (!ast_strlen_zero(p->uri)) 06205 c = p->uri; 06206 else { 06207 char *n; 06208 /* We have no URI, use To: or From: header as URI (depending on direction) */ 06209 ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"), 06210 sizeof(stripped)); 06211 n = get_in_brackets(stripped); 06212 c = strsep(&n, ";"); /* trim ; and beyond */ 06213 } 06214 init_req(req, sipmethod, c); 06215 06216 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 06217 06218 add_header(req, "Via", p->via); 06219 if (p->route) { 06220 set_destination(p, p->route->hop); 06221 add_route(req, is_strict ? p->route->next : p->route); 06222 } 06223 06224 ot = get_header(orig, "To"); 06225 of = get_header(orig, "From"); 06226 06227 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 06228 as our original request, including tag (or presumably lack thereof) */ 06229 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 06230 /* Add the proper tag if we don't have it already. If they have specified 06231 their tag, use it. Otherwise, use our own tag */ 06232 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 06233 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06234 else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06235 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06236 else 06237 snprintf(newto, sizeof(newto), "%s", ot); 06238 ot = newto; 06239 } 06240 06241 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06242 add_header(req, "From", of); 06243 add_header(req, "To", ot); 06244 } else { 06245 add_header(req, "From", ot); 06246 add_header(req, "To", of); 06247 } 06248 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 06249 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 06250 add_header(req, "Contact", p->our_contact); 06251 06252 copy_header(req, orig, "Call-ID"); 06253 add_header(req, "CSeq", tmp); 06254 06255 if (!ast_strlen_zero(global_useragent)) 06256 add_header(req, "User-Agent", global_useragent); 06257 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 06258 06259 if (!ast_strlen_zero(p->rpid)) 06260 add_header(req, "Remote-Party-ID", p->rpid); 06261 06262 return 0; 06263 }
static int resp_needs_contact | ( | const char * | msg, | |
enum sipmethod | method | |||
) | [inline, static] |
Test if this response needs a contact header.
Definition at line 6050 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().
06050 { 06051 /* Requirements for Contact header inclusion in responses generated 06052 * from the header tables found in the following RFCs. Where the 06053 * Contact header was marked mandatory (m) or optional (o) this 06054 * function returns 1. 06055 * 06056 * - RFC 3261 (ACK, BYE, CANCEL, INVITE, OPTIONS, REGISTER) 06057 * - RFC 2976 (INFO) 06058 * - RFC 3262 (PRACK) 06059 * - RFC 3265 (SUBSCRIBE, NOTIFY) 06060 * - RFC 3311 (UPDATE) 06061 * - RFC 3428 (MESSAGE) 06062 * - RFC 3515 (REFER) 06063 * - RFC 3903 (PUBLISH) 06064 */ 06065 06066 switch (method) { 06067 /* 1xx, 2xx, 3xx, 485 */ 06068 case SIP_INVITE: 06069 case SIP_UPDATE: 06070 case SIP_SUBSCRIBE: 06071 case SIP_NOTIFY: 06072 if ((msg[0] >= '1' && msg[0] <= '3') || !strncmp(msg, "485", 3)) 06073 return 1; 06074 break; 06075 06076 /* 2xx, 3xx, 485 */ 06077 case SIP_REGISTER: 06078 case SIP_OPTIONS: 06079 if (msg[0] == '2' || msg[0] == '3' || !strncmp(msg, "485", 3)) 06080 return 1; 06081 break; 06082 06083 /* 3xx, 485 */ 06084 case SIP_BYE: 06085 case SIP_PRACK: 06086 case SIP_MESSAGE: 06087 case SIP_PUBLISH: 06088 if (msg[0] == '3' || !strncmp(msg, "485", 3)) 06089 return 1; 06090 break; 06091 06092 /* 2xx, 3xx, 4xx, 5xx, 6xx */ 06093 case SIP_REFER: 06094 if (msg[0] >= '2' && msg[0] <= '6') 06095 return 1; 06096 break; 06097 06098 /* contact will not be included for everything else */ 06099 case SIP_ACK: 06100 case SIP_CANCEL: 06101 case SIP_INFO: 06102 case SIP_PING: 06103 default: 06104 return 0; 06105 } 06106 return 0; 06107 }
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 6111 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.
06112 { 06113 char newto[256]; 06114 const char *ot; 06115 06116 init_resp(resp, msg); 06117 copy_via_headers(p, resp, req, "Via"); 06118 if (msg[0] == '1' || msg[0] == '2') 06119 copy_all_header(resp, req, "Record-Route"); 06120 copy_header(resp, req, "From"); 06121 ot = get_header(req, "To"); 06122 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 06123 /* Add the proper tag if we don't have it already. If they have specified 06124 their tag, use it. Otherwise, use our own tag */ 06125 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06126 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06127 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06128 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06129 else 06130 ast_copy_string(newto, ot, sizeof(newto)); 06131 ot = newto; 06132 } 06133 add_header(resp, "To", ot); 06134 copy_header(resp, req, "Call-ID"); 06135 copy_header(resp, req, "CSeq"); 06136 if (!ast_strlen_zero(global_useragent)) 06137 add_header(resp, "User-Agent", global_useragent); 06138 add_header(resp, "Allow", ALLOWED_METHODS); 06139 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 06140 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 06141 /* For registration responses, we also need expiry and 06142 contact info */ 06143 char tmp[256]; 06144 06145 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 06146 add_header(resp, "Expires", tmp); 06147 if (p->expiry) { /* Only add contact if we have an expiry time */ 06148 char contact[SIPBUFSIZE]; 06149 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 06150 add_header(resp, "Contact", contact); /* Not when we unregister */ 06151 } 06152 } else if (!ast_strlen_zero(p->our_contact) && resp_needs_contact(msg, p->method)) { 06153 add_header(resp, "Contact", p->our_contact); 06154 } 06155 return 0; 06156 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 16665 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.
16666 { 16667 /* If we're supposed to be stopped -- stay stopped */ 16668 if (monitor_thread == AST_PTHREADT_STOP) 16669 return 0; 16670 ast_mutex_lock(&monlock); 16671 if (monitor_thread == pthread_self()) { 16672 ast_mutex_unlock(&monlock); 16673 ast_log(LOG_WARNING, "Cannot kill myself\n"); 16674 return -1; 16675 } 16676 if (monitor_thread != AST_PTHREADT_NULL) { 16677 /* Wake up the thread */ 16678 pthread_kill(monitor_thread, SIGURG); 16679 } else { 16680 /* Start a new monitor */ 16681 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 16682 ast_mutex_unlock(&monlock); 16683 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 16684 return -1; 16685 } 16686 } 16687 ast_mutex_unlock(&monlock); 16688 return 0; 16689 }
static int retrans_pkt | ( | const void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 1922 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.
01923 { 01924 struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL; 01925 int reschedule = DEFAULT_RETRANS; 01926 int xmitres = 0; 01927 01928 /* Lock channel PVT */ 01929 ast_mutex_lock(&pkt->owner->lock); 01930 01931 if (pkt->retrans < MAX_RETRANS) { 01932 pkt->retrans++; 01933 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 01934 if (sipdebug && option_debug > 3) 01935 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); 01936 } else { 01937 int siptimer_a; 01938 01939 if (sipdebug && option_debug > 3) 01940 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 01941 if (!pkt->timer_a) 01942 pkt->timer_a = 2 ; 01943 else 01944 pkt->timer_a = 2 * pkt->timer_a; 01945 01946 /* For non-invites, a maximum of 4 secs */ 01947 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 01948 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 01949 siptimer_a = 4000; 01950 01951 /* Reschedule re-transmit */ 01952 reschedule = siptimer_a; 01953 if (option_debug > 3) 01954 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); 01955 } 01956 01957 if (sip_debug_test_pvt(pkt->owner)) { 01958 const struct sockaddr_in *dst = sip_real_dst(pkt->owner); 01959 ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n", 01960 pkt->retrans, sip_nat_mode(pkt->owner), 01961 ast_inet_ntoa(dst->sin_addr), 01962 ntohs(dst->sin_port), pkt->data); 01963 } 01964 01965 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data); 01966 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 01967 ast_mutex_unlock(&pkt->owner->lock); 01968 if (xmitres == XMIT_ERROR) 01969 ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid); 01970 else 01971 return reschedule; 01972 } 01973 /* Too many retries */ 01974 if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) { 01975 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 01976 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); 01977 } else if ((pkt->method == SIP_OPTIONS) && sipdebug) { 01978 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) -- See doc/sip-retransmit.txt.\n", pkt->owner->callid); 01979 } 01980 if (xmitres == XMIT_ERROR) { 01981 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission of transaction in call id %s \n", pkt->owner->callid); 01982 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01983 } else 01984 append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01985 01986 pkt->retransid = -1; 01987 01988 if (ast_test_flag(pkt, FLAG_FATAL)) { 01989 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 01990 DEADLOCK_AVOIDANCE(&pkt->owner->lock); /* SIP_PVT, not channel */ 01991 } 01992 01993 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 01994 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 01995 01996 if (pkt->owner->owner) { 01997 sip_alreadygone(pkt->owner); 01998 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); 01999 ast_queue_hangup(pkt->owner->owner); 02000 ast_channel_unlock(pkt->owner->owner); 02001 } else { 02002 /* If no channel owner, destroy now */ 02003 02004 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 02005 if (pkt->method != SIP_OPTIONS) { 02006 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 02007 sip_alreadygone(pkt->owner); 02008 if (option_debug) 02009 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 02010 } 02011 } 02012 } 02013 02014 if (pkt->method == SIP_BYE) { 02015 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 02016 if (pkt->owner->owner) 02017 ast_channel_unlock(pkt->owner->owner); 02018 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 02019 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 02020 } 02021 02022 /* In any case, go ahead and remove the packet */ 02023 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 02024 if (cur == pkt) 02025 break; 02026 } 02027 if (cur) { 02028 if (prev) 02029 prev->next = cur->next; 02030 else 02031 pkt->owner->packets = cur->next; 02032 ast_mutex_unlock(&pkt->owner->lock); 02033 free(cur); 02034 pkt = NULL; 02035 } else 02036 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 02037 if (pkt) 02038 ast_mutex_unlock(&pkt->owner->lock); 02039 return 0; 02040 }
static int scheduler_process_request_queue | ( | const void * | data | ) | [static] |
Definition at line 16230 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().
16231 { 16232 struct sip_pvt *p = (struct sip_pvt *) data; 16233 int recount = 0; 16234 int nounlock = 0; 16235 int lockretry; 16236 16237 for (lockretry = 10; lockretry > 0; lockretry--) { 16238 ast_mutex_lock(&p->lock); 16239 16240 /* lock the owner if it has one -- we may need it */ 16241 /* because this is deadlock-prone, we need to try and unlock if failed */ 16242 if (!p->owner || !ast_channel_trylock(p->owner)) { 16243 break; /* locking succeeded */ 16244 } 16245 16246 if (lockretry != 1) { 16247 ast_mutex_unlock(&p->lock); 16248 /* Sleep for a very short amount of time */ 16249 usleep(1); 16250 } 16251 } 16252 16253 if (!lockretry) { 16254 int retry = !AST_LIST_EMPTY(&p->request_queue); 16255 16256 /* we couldn't get the owner lock, which is needed to process 16257 the queued requests, so return a non-zero value, which will 16258 cause the scheduler to run this request again later if there 16259 still requests to be processed 16260 */ 16261 ast_mutex_unlock(&p->lock); 16262 return retry; 16263 }; 16264 16265 process_request_queue(p, &recount, &nounlock); 16266 p->request_queue_sched_id = -1; 16267 16268 if (p->owner && !nounlock) { 16269 ast_channel_unlock(p->owner); 16270 } 16271 ast_mutex_unlock(&p->lock); 16272 16273 if (recount) { 16274 ast_update_use_count(); 16275 } 16276 16277 return 0; 16278 }
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 2320 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.
02321 { 02322 int res; 02323 02324 add_blank(req); 02325 if (sip_debug_test_pvt(p)) { 02326 if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)) 02327 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); 02328 else 02329 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); 02330 } 02331 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02332 struct sip_request tmp; 02333 parse_copy(&tmp, req); 02334 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 02335 } 02336 res = (reliable) ? 02337 __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02338 __sip_xmit(p, req->data, req->len); 02339 return res; 02340 }
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 2292 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.
02293 { 02294 int res; 02295 02296 add_blank(req); 02297 if (sip_debug_test_pvt(p)) { 02298 const struct sockaddr_in *dst = sip_real_dst(p); 02299 02300 ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n", 02301 reliable ? "Reliably " : "", sip_nat_mode(p), 02302 ast_inet_ntoa(dst->sin_addr), 02303 ntohs(dst->sin_port), req->data); 02304 } 02305 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02306 struct sip_request tmp; 02307 parse_copy(&tmp, req); 02308 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 02309 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text); 02310 } 02311 res = (reliable) ? 02312 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02313 __sip_xmit(p, req->data, req->len); 02314 if (res > 0) 02315 return 0; 02316 return res; 02317 }
static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 8360 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().
08361 { 08362 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 08363 /* NAT: Don't trust the contact field. Just use what they came to us 08364 with. */ 08365 pvt->sa = pvt->recv; 08366 return 0; 08367 } 08368 08369 return __set_address_from_contact(pvt->fullcontact, &pvt->sa); 08370 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
Set destination from SIP URI.
Definition at line 5960 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().
05961 { 05962 char *h, *maddr, hostname[256]; 05963 int port, hn; 05964 struct hostent *hp; 05965 struct ast_hostent ahp; 05966 int debug=sip_debug_test_pvt(p); 05967 05968 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 05969 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 05970 05971 if (debug) 05972 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 05973 05974 /* Find and parse hostname */ 05975 h = strchr(uri, '@'); 05976 if (h) 05977 ++h; 05978 else { 05979 h = uri; 05980 if (strncasecmp(h, "sip:", 4) == 0) 05981 h += 4; 05982 else if (strncasecmp(h, "sips:", 5) == 0) 05983 h += 5; 05984 } 05985 hn = strcspn(h, ":;>") + 1; 05986 if (hn > sizeof(hostname)) 05987 hn = sizeof(hostname); 05988 ast_copy_string(hostname, h, hn); 05989 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 05990 h += hn - 1; 05991 05992 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 05993 if (*h == ':') { 05994 /* Parse port */ 05995 ++h; 05996 port = strtol(h, &h, 10); 05997 } 05998 else 05999 port = STANDARD_SIP_PORT; 06000 06001 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 06002 maddr = strstr(h, "maddr="); 06003 if (maddr) { 06004 maddr += 6; 06005 hn = strspn(maddr, "0123456789.") + 1; 06006 if (hn > sizeof(hostname)) 06007 hn = sizeof(hostname); 06008 ast_copy_string(hostname, maddr, hn); 06009 } 06010 06011 hp = ast_gethostbyname(hostname, &ahp); 06012 if (hp == NULL) { 06013 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 06014 return; 06015 } 06016 p->sa.sin_family = AF_INET; 06017 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 06018 p->sa.sin_port = htons(port); 06019 if (debug) 06020 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 06021 }
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 17000 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().
17001 { 17002 static int dep_insecure_very = 0; 17003 static int dep_insecure_yes = 0; 17004 17005 if (ast_strlen_zero(value)) 17006 return; 17007 17008 if (!strcasecmp(value, "very")) { 17009 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 17010 if(!dep_insecure_very) { 17011 if(lineno != -1) 17012 ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno); 17013 else 17014 ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n"); 17015 dep_insecure_very = 1; 17016 } 17017 } 17018 else if (ast_true(value)) { 17019 ast_set_flag(flags, SIP_INSECURE_PORT); 17020 if(!dep_insecure_yes) { 17021 if(lineno != -1) 17022 ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno); 17023 else 17024 ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value); 17025 dep_insecure_yes = 1; 17026 } 17027 } 17028 else if (!ast_false(value)) { 17029 char buf[64]; 17030 char *word, *next; 17031 ast_copy_string(buf, value, sizeof(buf)); 17032 next = buf; 17033 while ((word = strsep(&next, ","))) { 17034 if (!strcasecmp(word, "port")) 17035 ast_set_flag(flags, SIP_INSECURE_PORT); 17036 else if (!strcasecmp(word, "invite")) 17037 ast_set_flag(flags, SIP_INSECURE_INVITE); 17038 else 17039 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 17040 } 17041 } 17042 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 17431 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().
17432 { 17433 if (peer->expire == 0) { 17434 /* Don't reset expire or port time during reload 17435 if we have an active registration 17436 */ 17437 peer->expire = -1; 17438 peer->pokeexpire = -1; 17439 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 17440 } 17441 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 17442 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 17443 strcpy(peer->context, default_context); 17444 strcpy(peer->subscribecontext, default_subscribecontext); 17445 strcpy(peer->language, default_language); 17446 strcpy(peer->mohinterpret, default_mohinterpret); 17447 strcpy(peer->mohsuggest, default_mohsuggest); 17448 peer->addr.sin_family = AF_INET; 17449 peer->defaddr.sin_family = AF_INET; 17450 peer->capability = global_capability; 17451 peer->maxcallbitrate = default_maxcallbitrate; 17452 peer->rtptimeout = global_rtptimeout; 17453 peer->rtpholdtimeout = global_rtpholdtimeout; 17454 peer->rtpkeepalive = global_rtpkeepalive; 17455 peer->allowtransfer = global_allowtransfer; 17456 peer->autoframing = global_autoframing; 17457 strcpy(peer->vmexten, default_vmexten); 17458 peer->secret[0] = '\0'; 17459 peer->md5secret[0] = '\0'; 17460 peer->cid_num[0] = '\0'; 17461 peer->cid_name[0] = '\0'; 17462 peer->fromdomain[0] = '\0'; 17463 peer->fromuser[0] = '\0'; 17464 peer->regexten[0] = '\0'; 17465 peer->mailbox[0] = '\0'; 17466 peer->callgroup = 0; 17467 peer->pickupgroup = 0; 17468 peer->maxms = default_qualify; 17469 peer->prefs = default_prefs; 17470 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 18731 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().
18732 { 18733 int no = 0; 18734 int ok = FALSE; 18735 char varbuf[30]; 18736 char *inbuf = (char *) data; 18737 18738 if (ast_strlen_zero(inbuf)) { 18739 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 18740 return 0; 18741 } 18742 ast_channel_lock(chan); 18743 18744 /* Check for headers */ 18745 while (!ok && no <= 50) { 18746 no++; 18747 snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no); 18748 18749 /* Compare without the leading underscores */ 18750 if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL) ) 18751 ok = TRUE; 18752 } 18753 if (ok) { 18754 pbx_builtin_setvar_helper (chan, varbuf, inbuf); 18755 if (sipdebug) 18756 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf); 18757 } else { 18758 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 18759 } 18760 ast_channel_unlock(chan); 18761 return 0; 18762 }
static int sip_addrcmp | ( | char * | name, | |
struct sockaddr_in * | sin | |||
) | [static] |
Support routine for find_peer.
Definition at line 2690 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, inaddrcmp(), and SIP_INSECURE_PORT.
Referenced by find_peer().
02691 { 02692 /* We know name is the first field, so we can cast */ 02693 struct sip_peer *p = (struct sip_peer *) name; 02694 return !(!inaddrcmp(&p->addr, sin) || 02695 (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) && 02696 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 02697 }
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 4563 of file chan_sip.c.
References __ourip, ast_calloc, ast_copy_flags, AST_LIST_HEAD_INIT_NOLOCK, ast_log(), ast_mutex_destroy(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_rtp_codec_setpref(), AST_RTP_DTMF, ast_rtp_new_with_bindaddr(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_settos(), ast_set2_flag, ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_set, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_new_with_bindaddr(), ast_udptl_settos(), ast_variables_destroy(), bindaddr, build_callid_pvt(), build_via(), context, default_prefs, do_setnat(), errno, free, sip_pvt::fromdomain, global_flags, iflist, iflock, INITIAL_CSEQ, io, LOG_DEBUG, make_our_tag(), mohinterpret, mohsuggest, NONE, option_debug, sched, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, SIP_OPTIONS, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_REGISTER, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, text, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.
Referenced by sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
04565 { 04566 struct sip_pvt *p; 04567 04568 if (!(p = ast_calloc(1, sizeof(*p)))) 04569 return NULL; 04570 04571 if (ast_string_field_init(p, 512)) { 04572 free(p); 04573 return NULL; 04574 } 04575 04576 ast_mutex_init(&p->lock); 04577 04578 p->method = intended_method; 04579 p->initid = -1; 04580 p->waitid = -1; 04581 p->autokillid = -1; 04582 p->request_queue_sched_id = -1; 04583 p->subscribed = NONE; 04584 p->stateid = -1; 04585 p->prefs = default_prefs; /* Set default codecs for this call */ 04586 04587 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 04588 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 04589 04590 if (sin) { 04591 p->sa = *sin; 04592 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 04593 p->ourip = __ourip; 04594 } else 04595 p->ourip = __ourip; 04596 04597 /* Copy global flags to this PVT at setup. */ 04598 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 04599 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 04600 04601 ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY); 04602 04603 p->branch = ast_random(); 04604 make_our_tag(p->tag, sizeof(p->tag)); 04605 p->ocseq = INITIAL_CSEQ; 04606 04607 if (sip_methods[intended_method].need_rtp) { 04608 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04609 /* If the global videosupport flag is on, we always create a RTP interface for video */ 04610 if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 04611 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04612 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) 04613 p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 04614 if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) { 04615 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", 04616 ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno)); 04617 ast_mutex_destroy(&p->lock); 04618 if (p->chanvars) { 04619 ast_variables_destroy(p->chanvars); 04620 p->chanvars = NULL; 04621 } 04622 free(p); 04623 return NULL; 04624 } 04625 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04626 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04627 ast_rtp_settos(p->rtp, global_tos_audio); 04628 ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); 04629 ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); 04630 ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); 04631 if (p->vrtp) { 04632 ast_rtp_settos(p->vrtp, global_tos_video); 04633 ast_rtp_setdtmf(p->vrtp, 0); 04634 ast_rtp_setdtmfcompensate(p->vrtp, 0); 04635 ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); 04636 ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout); 04637 ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); 04638 } 04639 if (p->udptl) 04640 ast_udptl_settos(p->udptl, global_tos_audio); 04641 p->maxcallbitrate = default_maxcallbitrate; 04642 p->autoframing = global_autoframing; 04643 ast_rtp_codec_setpref(p->rtp, &p->prefs); 04644 } 04645 04646 if (useglobal_nat && sin) { 04647 /* Setup NAT structure according to global settings if we have an address */ 04648 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 04649 p->recv = *sin; 04650 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04651 } 04652 04653 if (p->method != SIP_REGISTER) 04654 ast_string_field_set(p, fromdomain, default_fromdomain); 04655 build_via(p); 04656 if (!callid) 04657 build_callid_pvt(p); 04658 else 04659 ast_string_field_set(p, callid, callid); 04660 /* Assign default music on hold class */ 04661 ast_string_field_set(p, mohinterpret, default_mohinterpret); 04662 ast_string_field_set(p, mohsuggest, default_mohsuggest); 04663 p->capability = global_capability; 04664 p->allowtransfer = global_allowtransfer; 04665 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 04666 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 04667 p->noncodeccapability |= AST_RTP_DTMF; 04668 if (p->udptl) { 04669 p->t38.capability = global_t38_capability; 04670 if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY) 04671 p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 04672 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC) 04673 p->t38.capability |= T38FAX_UDP_EC_FEC; 04674 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE) 04675 p->t38.capability |= T38FAX_UDP_EC_NONE; 04676 p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 04677 p->t38.jointcapability = p->t38.capability; 04678 } 04679 ast_string_field_set(p, context, default_context); 04680 04681 AST_LIST_HEAD_INIT_NOLOCK(&p->request_queue); 04682 04683 /* Add to active dialog list */ 04684 ast_mutex_lock(&iflock); 04685 p->next = iflist; 04686 iflist = p; 04687 ast_mutex_unlock(&iflock); 04688 if (option_debug) 04689 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"); 04690 return p; 04691 }
static void sip_alreadygone | ( | struct sip_pvt * | dialog | ) | [static] |
Definition at line 1673 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().
01674 { 01675 if (option_debug > 2) 01676 ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 01677 ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE); 01678 }
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 3751 of file chan_sip.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_setstate(), AST_STATE_UP, sip_pvt::lock, LOG_DEBUG, ast_channel::name, option_debug, SIP_PAGE2_DIALOG_ESTABLISHED, T38_ENABLED, T38_PEER_DIRECT, ast_channel::tech_pvt, transmit_response_with_sdp(), transmit_response_with_t38_sdp(), try_suggested_sip_codec(), and XMIT_CRITICAL.
03752 { 03753 int res = 0; 03754 struct sip_pvt *p = ast->tech_pvt; 03755 03756 ast_mutex_lock(&p->lock); 03757 if (ast->_state != AST_STATE_UP) { 03758 try_suggested_sip_codec(p); 03759 03760 ast_setstate(ast, AST_STATE_UP); 03761 if (option_debug) 03762 ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name); 03763 if (p->t38.state == T38_PEER_DIRECT) { 03764 p->t38.state = T38_ENABLED; 03765 if (option_debug > 1) 03766 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 03767 res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03768 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 03769 } else { 03770 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03771 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 03772 } 03773 } 03774 ast_mutex_unlock(&p->lock); 03775 return res; 03776 }
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 3017 of file chan_sip.c.
References ast_channel::_state, sip_invite_param::addsipheaders, AST_CAUSE_USER_BUSY, AST_FORMAT_AUDIO_MASK, AST_LIST_TRAVERSE, ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_string_field_set, ast_translate_available_formats(), ast_var_name(), ast_var_value(), auto_congest(), sip_pvt::callingpres, t38properties::capability, sip_pvt::capability, ast_channel::cid, cid_name, sip_pvt::cid_name, ast_callerid::cid_pres, sip_invite_param::distinctive_ring, ast_var_t::entries, sip_pvt::flags, ast_channel::hangupcause, INC_CALL_RINGING, sip_pvt::initid, INV_CALLING, sip_pvt::invitestate, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, LOG_DEBUG, sip_pvt::maxtime, ast_channel::name, sip_pvt::noncodeccapability, option_debug, sip_pvt::options, sip_pvt::prefcodec, sip_invite_param::replaces, sched, SIP_INVITE, SIP_OUTGOING, SIP_TRANS_TIMEOUT, SIPBUFSIZE, sipdebug, t38properties::state, sip_pvt::t38, T38_LOCAL_DIRECT, ast_channel::tech_pvt, sip_invite_param::transfer, transmit_invite(), update_call_counter(), sip_invite_param::uri_options, sip_pvt::username, ast_channel::varshead, sip_invite_param::vxml_url, and XMIT_ERROR.
03018 { 03019 int res, xmitres = 0; 03020 struct sip_pvt *p; 03021 struct varshead *headp; 03022 struct ast_var_t *current; 03023 const char *referer = NULL; /* SIP refererer */ 03024 03025 p = ast->tech_pvt; 03026 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 03027 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 03028 return -1; 03029 } 03030 03031 /* Check whether there is vxml_url, distinctive ring variables */ 03032 headp=&ast->varshead; 03033 AST_LIST_TRAVERSE(headp,current,entries) { 03034 /* Check whether there is a VXML_URL variable */ 03035 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 03036 p->options->vxml_url = ast_var_value(current); 03037 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 03038 p->options->uri_options = ast_var_value(current); 03039 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 03040 /* Check whether there is a ALERT_INFO variable */ 03041 p->options->distinctive_ring = ast_var_value(current); 03042 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 03043 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 03044 p->options->addsipheaders = 1; 03045 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 03046 /* This is a transfered call */ 03047 p->options->transfer = 1; 03048 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 03049 /* This is the referer */ 03050 referer = ast_var_value(current); 03051 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 03052 /* We're replacing a call. */ 03053 p->options->replaces = ast_var_value(current); 03054 } else if (!strcasecmp(ast_var_name(current), "T38CALL")) { 03055 p->t38.state = T38_LOCAL_DIRECT; 03056 if (option_debug) 03057 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 03058 } 03059 03060 } 03061 03062 res = 0; 03063 ast_set_flag(&p->flags[0], SIP_OUTGOING); 03064 03065 if (p->options->transfer) { 03066 char buf[SIPBUFSIZE/2]; 03067 03068 if (referer) { 03069 if (sipdebug && option_debug > 2) 03070 ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer); 03071 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 03072 } else 03073 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 03074 ast_string_field_set(p, cid_name, buf); 03075 } 03076 if (option_debug) 03077 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 03078 03079 res = update_call_counter(p, INC_CALL_RINGING); 03080 if ( res != -1 ) { 03081 p->callingpres = ast->cid.cid_pres; 03082 p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec); 03083 p->jointnoncodeccapability = p->noncodeccapability; 03084 03085 /* If there are no audio formats left to offer, punt */ 03086 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 03087 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 03088 res = -1; 03089 } else { 03090 p->t38.jointcapability = p->t38.capability; 03091 if (option_debug > 1) 03092 ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability); 03093 xmitres = transmit_invite(p, SIP_INVITE, 1, 2); 03094 if (xmitres == XMIT_ERROR) 03095 return -1; /* Transmission error */ 03096 03097 p->invitestate = INV_CALLING; 03098 03099 /* Initialize auto-congest time */ 03100 AST_SCHED_DEL(sched, p->initid); 03101 p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p); 03102 } 03103 } else { 03104 ast->hangupcause = AST_CAUSE_USER_BUSY; 03105 } 03106 return res; 03107 }
static int sip_cancel_destroy | ( | struct sip_pvt * | p | ) | [static] |
Cancel destruction of SIP dialog.
Definition at line 2162 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().
02163 { 02164 int res = 0; 02165 if (p->autokillid > -1) { 02166 if (!(res = ast_sched_del(sched, p->autokillid))) { 02167 append_history(p, "CancelDestroy", ""); 02168 p->autokillid = -1; 02169 } 02170 } 02171 return res; 02172 }
static int sip_debug_test_addr | ( | const struct sockaddr_in * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 1755 of file chan_sip.c.
References sipdebug.
Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().
01756 { 01757 if (!sipdebug) 01758 return 0; 01759 if (debugaddr.sin_addr.s_addr) { 01760 if (((ntohs(debugaddr.sin_port) != 0) 01761 && (debugaddr.sin_port != addr->sin_port)) 01762 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01763 return 0; 01764 } 01765 return 1; 01766 }
static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 1781 of file chan_sip.c.
References sip_debug_test_addr(), sip_real_dst(), and sipdebug.
Referenced by __sip_destroy(), add_sdp(), add_t38_sdp(), build_route(), check_via(), do_register_auth(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), handle_request(), process_sdp(), receive_message(), retrans_pkt(), send_request(), send_response(), set_destination(), sip_scheddestroy(), sip_sendtext(), and transmit_register().
01782 { 01783 if (!sipdebug) 01784 return 0; 01785 return sip_debug_test_addr(sip_real_dst(p)); 01786 }
static void sip_destroy | ( | struct sip_pvt * | p | ) | [static] |
Destroy SIP call structure.
Definition at line 3389 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().
03390 { 03391 ast_mutex_lock(&iflock); 03392 if (option_debug > 2) 03393 ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid); 03394 __sip_destroy(p, 1); 03395 ast_mutex_unlock(&iflock); 03396 }
static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 2500 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().
02501 { 02502 if (option_debug > 2) 02503 ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name); 02504 02505 /* Delete it, it needs to disappear */ 02506 if (peer->call) 02507 sip_destroy(peer->call); 02508 02509 if (peer->mwipvt) /* We have an active subscription, delete it */ 02510 sip_destroy(peer->mwipvt); 02511 02512 if (peer->chanvars) { 02513 ast_variables_destroy(peer->chanvars); 02514 peer->chanvars = NULL; 02515 } 02516 02517 register_peer_exten(peer, FALSE); 02518 ast_free_ha(peer->ha); 02519 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT)) 02520 apeerobjs--; 02521 else if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) 02522 rpeerobjs--; 02523 else 02524 speerobjs--; 02525 clear_realm_authentication(peer->auth); 02526 peer->auth = NULL; 02527 free(peer); 02528 }
static void sip_destroy_user | ( | struct sip_user * | user | ) | [static] |
Remove user object from in-memory storage.
Definition at line 2718 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().
02719 { 02720 if (option_debug > 2) 02721 ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name); 02722 ast_free_ha(user->ha); 02723 if (user->chanvars) { 02724 ast_variables_destroy(user->chanvars); 02725 user->chanvars = NULL; 02726 } 02727 if (ast_test_flag(&user->flags[0], SIP_REALTIME)) 02728 ruserobjs--; 02729 else 02730 suserobjs--; 02731 free(user); 02732 }
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 16835 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().
16836 { 16837 char *host; 16838 char *tmp; 16839 16840 struct hostent *hp; 16841 struct ast_hostent ahp; 16842 struct sip_peer *p; 16843 16844 int res = AST_DEVICE_INVALID; 16845 16846 /* make sure data is not null. Maybe unnecessary, but better be safe */ 16847 host = ast_strdupa(data ? data : ""); 16848 if ((tmp = strchr(host, '@'))) 16849 host = tmp + 1; 16850 16851 if (option_debug > 2) 16852 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 16853 16854 /* If find_peer asks for a realtime peer, then this breaks rtautoclear. This 16855 * is because when a peer tries to autoexpire, the last thing it does is to 16856 * queue up an event telling the system that the devicestate has changed 16857 * (presumably to unavailable). If we ask for a realtime peer here, this would 16858 * load it BACK into memory, thus defeating the point of trying to trying to 16859 * clear dead hosts out of memory. 16860 */ 16861 if ((p = find_peer(host, NULL, 0, 1))) { 16862 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 16863 /* we have an address for the peer */ 16864 16865 /* Check status in this order 16866 - Hold 16867 - Ringing 16868 - Busy (enforced only by call limit) 16869 - Inuse (we have a call) 16870 - Unreachable (qualify) 16871 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 16872 for registered devices */ 16873 16874 if (p->onHold) 16875 /* First check for hold or ring states */ 16876 res = AST_DEVICE_ONHOLD; 16877 else if (p->inRinging) { 16878 if (p->inRinging == p->inUse) 16879 res = AST_DEVICE_RINGING; 16880 else 16881 res = AST_DEVICE_RINGINUSE; 16882 } else if (p->call_limit && (p->inUse == p->call_limit)) 16883 /* check call limit */ 16884 res = AST_DEVICE_BUSY; 16885 else if (p->call_limit && p->inUse) 16886 /* Not busy, but we do have a call */ 16887 res = AST_DEVICE_INUSE; 16888 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 16889 /* We don't have a call. Are we reachable at all? Requires qualify= */ 16890 res = AST_DEVICE_UNAVAILABLE; 16891 else /* Default reply if we're registered and have no other data */ 16892 res = AST_DEVICE_NOT_INUSE; 16893 } else { 16894 /* there is no address, it's unavailable */ 16895 res = AST_DEVICE_UNAVAILABLE; 16896 } 16897 ASTOBJ_UNREF(p,sip_destroy_peer); 16898 } else { 16899 char *port = strchr(host, ':'); 16900 if (port) 16901 *port = '\0'; 16902 hp = ast_gethostbyname(host, &ahp); 16903 if (hp) 16904 res = AST_DEVICE_UNKNOWN; 16905 } 16906 16907 return res; 16908 }
static int sip_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 11728 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.
11729 { 11730 int oldsipdebug = sipdebug_console; 11731 if (argc != 3) { 11732 if (argc != 5) 11733 return RESULT_SHOWUSAGE; 11734 else if (strcmp(argv[3], "ip") == 0) 11735 return sip_do_debug_ip(fd, argc, argv); 11736 else if (strcmp(argv[3], "peer") == 0) 11737 return sip_do_debug_peer(fd, argc, argv); 11738 else 11739 return RESULT_SHOWUSAGE; 11740 } 11741 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11742 memset(&debugaddr, 0, sizeof(debugaddr)); 11743 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11744 return RESULT_SUCCESS; 11745 }
static int sip_do_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11747 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.
11748 { 11749 int oldsipdebug = sipdebug_console; 11750 char *newargv[6] = { "sip", "set", "debug", NULL }; 11751 if (argc != 2) { 11752 if (argc != 4) 11753 return RESULT_SHOWUSAGE; 11754 else if (strcmp(argv[2], "ip") == 0) { 11755 newargv[3] = argv[2]; 11756 newargv[4] = argv[3]; 11757 return sip_do_debug_ip(fd, argc + 1, newargv); 11758 } else if (strcmp(argv[2], "peer") == 0) { 11759 newargv[3] = argv[2]; 11760 newargv[4] = argv[3]; 11761 return sip_do_debug_peer(fd, argc + 1, newargv); 11762 } else 11763 return RESULT_SHOWUSAGE; 11764 } 11765 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11766 memset(&debugaddr, 0, sizeof(debugaddr)); 11767 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11768 return RESULT_SUCCESS; 11769 }
static int sip_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP Debugging in CLI.
Definition at line 11674 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().
11675 { 11676 struct hostent *hp; 11677 struct ast_hostent ahp; 11678 int port = 0; 11679 char *p, *arg; 11680 11681 /* sip set debug ip <ip> */ 11682 if (argc != 5) 11683 return RESULT_SHOWUSAGE; 11684 p = arg = argv[4]; 11685 strsep(&p, ":"); 11686 if (p) 11687 port = atoi(p); 11688 hp = ast_gethostbyname(arg, &ahp); 11689 if (hp == NULL) 11690 return RESULT_SHOWUSAGE; 11691 11692 debugaddr.sin_family = AF_INET; 11693 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 11694 debugaddr.sin_port = htons(port); 11695 if (port == 0) 11696 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 11697 else 11698 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 11699 11700 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11701 11702 return RESULT_SUCCESS; 11703 }
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 11706 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().
11707 { 11708 struct sip_peer *peer; 11709 if (argc != 5) 11710 return RESULT_SHOWUSAGE; 11711 peer = find_peer(argv[4], NULL, 1, 0); 11712 if (peer) { 11713 if (peer->addr.sin_addr.s_addr) { 11714 debugaddr.sin_family = AF_INET; 11715 debugaddr.sin_addr = peer->addr.sin_addr; 11716 debugaddr.sin_port = peer->addr.sin_port; 11717 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 11718 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11719 } else 11720 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]); 11721 ASTOBJ_UNREF(peer,sip_destroy_peer); 11722 } else 11723 ast_cli(fd, "No such peer '%s'\n", argv[4]); 11724 return RESULT_SUCCESS; 11725 }
static int sip_do_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP History logging (CLI).
Definition at line 11847 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and TRUE.
11848 { 11849 if (argc != 2) { 11850 return RESULT_SHOWUSAGE; 11851 } 11852 recordhistory = TRUE; 11853 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 11854 return RESULT_SUCCESS; 11855 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 18877 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().
18878 { 18879 reload_config(reason); 18880 18881 /* Prune peers who still are supposed to be deleted */ 18882 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 18883 if (option_debug > 3) 18884 ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n"); 18885 18886 /* Send qualify (OPTIONS) to all peers */ 18887 sip_poke_all_peers(); 18888 18889 /* Register with all services */ 18890 sip_send_all_registers(); 18891 18892 if (option_debug > 3) 18893 ast_log(LOG_DEBUG, "--------------- SIP reload done\n"); 18894 18895 return 0; 18896 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 18676 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().
18677 { 18678 struct sip_pvt *p; 18679 char *mode; 18680 if (data) 18681 mode = (char *)data; 18682 else { 18683 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 18684 return 0; 18685 } 18686 ast_channel_lock(chan); 18687 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 18688 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 18689 ast_channel_unlock(chan); 18690 return 0; 18691 } 18692 p = chan->tech_pvt; 18693 if (!p) { 18694 ast_channel_unlock(chan); 18695 return 0; 18696 } 18697 ast_mutex_lock(&p->lock); 18698 if (!strcasecmp(mode,"info")) { 18699 ast_clear_flag(&p->flags[0], SIP_DTMF); 18700 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 18701 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 18702 } else if (!strcasecmp(mode,"rfc2833")) { 18703 ast_clear_flag(&p->flags[0], SIP_DTMF); 18704 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 18705 p->jointnoncodeccapability |= AST_RTP_DTMF; 18706 } else if (!strcasecmp(mode,"inband")) { 18707 ast_clear_flag(&p->flags[0], SIP_DTMF); 18708 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 18709 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 18710 } else 18711 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 18712 if (p->rtp) 18713 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 18714 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 18715 if (!p->vad) { 18716 p->vad = ast_dsp_new(); 18717 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 18718 } 18719 } else { 18720 if (p->vad) { 18721 ast_dsp_free(p->vad); 18722 p->vad = NULL; 18723 } 18724 } 18725 ast_mutex_unlock(&p->lock); 18726 ast_channel_unlock(chan); 18727 return 0; 18728 }
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 11532 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().
11533 { 11534 int x = 0; 11535 struct sip_history *hist; 11536 static int errmsg = 0; 11537 11538 if (!dialog) 11539 return; 11540 11541 if (!option_debug && !sipdebug) { 11542 if (!errmsg) { 11543 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 11544 errmsg = 1; 11545 } 11546 return; 11547 } 11548 11549 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 11550 if (dialog->subscribed) 11551 ast_log(LOG_DEBUG, " * Subscription\n"); 11552 else 11553 ast_log(LOG_DEBUG, " * SIP Call\n"); 11554 if (dialog->history) 11555 AST_LIST_TRAVERSE(dialog->history, hist, list) 11556 ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); 11557 if (!x) 11558 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 11559 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 11560 }
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 3859 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.
03860 { 03861 int ret = -1; 03862 struct sip_pvt *p; 03863 03864 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug) 03865 ast_log(LOG_DEBUG, "New channel is zombie\n"); 03866 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug) 03867 ast_log(LOG_DEBUG, "Old channel is zombie\n"); 03868 03869 if (!newchan || !newchan->tech_pvt) { 03870 if (!newchan) 03871 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 03872 else 03873 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 03874 return -1; 03875 } 03876 p = newchan->tech_pvt; 03877 03878 if (!p) { 03879 ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n"); 03880 return -1; 03881 } 03882 03883 ast_mutex_lock(&p->lock); 03884 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 03885 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 03886 if (p->owner != oldchan) 03887 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 03888 else { 03889 p->owner = newchan; 03890 /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native 03891 RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be 03892 able to do this if the masquerade happens before the bridge breaks (e.g., AMI 03893 redirect of both channels). Note that a channel can not be masqueraded *into* 03894 a native bridge. So there is no danger that this breaks a native bridge that 03895 should stay up. */ 03896 sip_set_rtp_peer(newchan, NULL, NULL, 0, 0); 03897 ret = 0; 03898 } 03899 if (option_debug > 2) 03900 ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 03901 03902 ast_mutex_unlock(&p->lock); 03903 return ret; 03904 }
static int sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Return SIP UA's codec (part of the RTP interface).
Definition at line 18821 of file chan_sip.c.
References sip_pvt::capability, sip_pvt::jointcapability, and ast_channel::tech_pvt.
18822 { 18823 struct sip_pvt *p = chan->tech_pvt; 18824 return p->jointcapability ? p->jointcapability : p->capability; 18825 }
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 18529 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.
18530 { 18531 struct sip_pvt *p = NULL; 18532 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 18533 18534 if (!(p = chan->tech_pvt)) 18535 return AST_RTP_GET_FAILED; 18536 18537 ast_mutex_lock(&p->lock); 18538 if (!(p->rtp)) { 18539 ast_mutex_unlock(&p->lock); 18540 return AST_RTP_GET_FAILED; 18541 } 18542 18543 *rtp = p->rtp; 18544 18545 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 18546 res = AST_RTP_TRY_PARTIAL; 18547 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 18548 res = AST_RTP_TRY_NATIVE; 18549 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 18550 res = AST_RTP_GET_FAILED; 18551 18552 ast_mutex_unlock(&p->lock); 18553 18554 return res; 18555 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 18394 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.
18395 { 18396 struct sip_pvt *p; 18397 struct ast_udptl *udptl = NULL; 18398 18399 p = chan->tech_pvt; 18400 if (!p) 18401 return NULL; 18402 18403 ast_mutex_lock(&p->lock); 18404 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 18405 udptl = p->udptl; 18406 ast_mutex_unlock(&p->lock); 18407 return udptl; 18408 }
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 18558 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.
18559 { 18560 struct sip_pvt *p = NULL; 18561 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 18562 18563 if (!(p = chan->tech_pvt)) 18564 return AST_RTP_GET_FAILED; 18565 18566 ast_mutex_lock(&p->lock); 18567 if (!(p->vrtp)) { 18568 ast_mutex_unlock(&p->lock); 18569 return AST_RTP_GET_FAILED; 18570 } 18571 18572 *rtp = p->vrtp; 18573 18574 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 18575 res = AST_RTP_TRY_NATIVE; 18576 18577 ast_mutex_unlock(&p->lock); 18578 18579 return res; 18580 }
static int sip_handle_t38_reinvite | ( | struct ast_channel * | chan, | |
struct sip_pvt * | pvt, | |||
int | reinvite | |||
) | [static] |
Handle T38 reinvite.
Definition at line 18446 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().
18447 { 18448 struct sip_pvt *p; 18449 int flag = 0; 18450 18451 p = chan->tech_pvt; 18452 if (!p || !pvt->udptl) 18453 return -1; 18454 18455 /* Setup everything on the other side like offered/responded from first side */ 18456 ast_mutex_lock(&p->lock); 18457 18458 /*! \todo check if this is not set earlier when setting up the PVT. If not 18459 maybe it should move there. */ 18460 p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability; 18461 18462 ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 18463 ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 18464 ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl)); 18465 18466 if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */ 18467 /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects, 18468 not really T38 re-invites which are different. In this 18469 case it's used properly, to see if we can reinvite over 18470 NAT 18471 */ 18472 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 18473 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 18474 flag =1; 18475 } else { 18476 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18477 } 18478 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 18479 if (!p->pendinginvite) { 18480 if (option_debug > 2) { 18481 if (flag) 18482 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)); 18483 else 18484 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)); 18485 } 18486 transmit_reinvite_with_t38_sdp(p); 18487 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18488 if (option_debug > 2) { 18489 if (flag) 18490 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)); 18491 else 18492 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)); 18493 } 18494 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18495 } 18496 } 18497 /* Reset lastrtprx timer */ 18498 p->lastrtprx = p->lastrtptx = time(NULL); 18499 ast_mutex_unlock(&p->lock); 18500 return 0; 18501 } else { /* If we are handling sending 200 OK to the other side of the bridge */ 18502 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 18503 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 18504 flag = 1; 18505 } else { 18506 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18507 } 18508 if (option_debug > 2) { 18509 if (flag) 18510 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)); 18511 else 18512 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)); 18513 } 18514 pvt->t38.state = T38_ENABLED; 18515 p->t38.state = T38_ENABLED; 18516 if (option_debug > 1) { 18517 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 18518 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 18519 } 18520 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 18521 p->lastrtprx = p->lastrtptx = time(NULL); 18522 ast_mutex_unlock(&p->lock); 18523 return 0; 18524 } 18525 }
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 3562 of file chan_sip.c.
References __sip_pretend_ack(), ast_channel::_state, append_history, ast_cause2str(), ast_clear_flag, ast_dsp_free(), AST_FLAG_ZOMBIE, ast_log(), ast_module_unref(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_quality(), AST_SCHED_DEL, ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, sip_pvt::autokillid, sip_pvt::callid, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, sip_pvt::hangupcause, INC_CALL_LIMIT, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, sched, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_DEFER_BYE_ON_TRANSFER, SIP_INC_COUNT, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_PAGE2_CALL_ONHOLD, SIP_PENDINGBYE, sip_scheddestroy(), sipdebug, stop_media_flows(), ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, update_call_counter(), sip_pvt::username, sip_pvt::vad, and XMIT_RELIABLE.
03563 { 03564 struct sip_pvt *p = ast->tech_pvt; 03565 int needcancel = FALSE; 03566 int needdestroy = 0; 03567 struct ast_channel *oldowner = ast; 03568 03569 if (!p) { 03570 if (option_debug) 03571 ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n"); 03572 return 0; 03573 } 03574 03575 /* Store hangupcause locally in PVT so we still have it before disconnect */ 03576 if (p->owner) 03577 p->hangupcause = p->owner->hangupcause; 03578 03579 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 03580 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03581 if (option_debug && sipdebug) 03582 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03583 update_call_counter(p, DEC_CALL_LIMIT); 03584 } 03585 if (option_debug >3) 03586 ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 03587 if (p->autokillid > -1 && sip_cancel_destroy(p)) 03588 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03589 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03590 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 03591 ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY); 03592 p->owner->tech_pvt = NULL; 03593 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 03594 return 0; 03595 } 03596 if (option_debug) { 03597 if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug) 03598 ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 03599 else { 03600 if (option_debug) 03601 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 03602 } 03603 } 03604 if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 03605 ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n"); 03606 03607 ast_mutex_lock(&p->lock); 03608 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03609 if (option_debug && sipdebug) 03610 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03611 update_call_counter(p, DEC_CALL_LIMIT); 03612 } 03613 03614 /* Determine how to disconnect */ 03615 if (p->owner != ast) { 03616 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 03617 ast_mutex_unlock(&p->lock); 03618 return 0; 03619 } 03620 /* If the call is not UP, we need to send CANCEL instead of BYE */ 03621 if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) { 03622 needcancel = TRUE; 03623 if (option_debug > 3) 03624 ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 03625 } 03626 03627 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 03628 03629 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->hangupcause) : "Unknown"); 03630 03631 /* Disconnect */ 03632 if (p->vad) 03633 ast_dsp_free(p->vad); 03634 03635 p->owner = NULL; 03636 ast->tech_pvt = NULL; 03637 03638 ast_module_unref(ast_module_info->self); 03639 03640 /* Do not destroy this pvt until we have timeout or 03641 get an answer to the BYE or INVITE/CANCEL 03642 If we get no answer during retransmit period, drop the call anyway. 03643 (Sorry, mother-in-law, you can't deny a hangup by sending 03644 603 declined to BYE...) 03645 */ 03646 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) 03647 needdestroy = 1; /* Set destroy flag at end of this function */ 03648 else if (p->invitestate != INV_CALLING) 03649 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03650 03651 /* Start the process if it's not already started */ 03652 if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 03653 if (needcancel) { /* Outgoing call, not up */ 03654 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03655 /* stop retransmitting an INVITE that has not received a response */ 03656 __sip_pretend_ack(p); 03657 p->invitestate = INV_CANCELLED; 03658 03659 /* if we can't send right now, mark it pending */ 03660 if (p->invitestate == INV_CALLING) { 03661 /* We can't send anything in CALLING state */ 03662 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03663 /* 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. */ 03664 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03665 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 03666 } else { 03667 /* Send a new request: CANCEL */ 03668 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 03669 /* Actually don't destroy us yet, wait for the 487 on our original 03670 INVITE, but do set an autodestruct just in case we never get it. */ 03671 needdestroy = 0; 03672 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03673 } 03674 if ( p->initid != -1 ) { 03675 /* channel still up - reverse dec of inUse counter 03676 only if the channel is not auto-congested */ 03677 update_call_counter(p, INC_CALL_LIMIT); 03678 } 03679 } else { /* Incoming call, not up */ 03680 const char *res; 03681 if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause))) 03682 transmit_response_reliable(p, res, &p->initreq); 03683 else 03684 transmit_response_reliable(p, "603 Declined", &p->initreq); 03685 p->invitestate = INV_TERMINATED; 03686 } 03687 } else { /* Call is in UP state, send BYE */ 03688 if (!p->pendinginvite) { 03689 char *audioqos = ""; 03690 char *videoqos = ""; 03691 if (p->rtp) 03692 audioqos = ast_rtp_get_quality(p->rtp, NULL); 03693 if (p->vrtp) 03694 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 03695 /* Send a hangup */ 03696 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03697 03698 /* Get RTCP quality before end of call */ 03699 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 03700 if (p->rtp) 03701 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 03702 if (p->vrtp) 03703 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 03704 } 03705 if (p->rtp && oldowner) 03706 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); 03707 if (p->vrtp && oldowner) 03708 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos); 03709 } else { 03710 /* Note we will need a BYE when this all settles out 03711 but we can't send one while we have "INVITE" outstanding. */ 03712 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03713 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 03714 AST_SCHED_DEL(sched, p->waitid); 03715 if (sip_cancel_destroy(p)) 03716 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03717 } 03718 } 03719 } 03720 if (needdestroy) 03721 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 03722 ast_mutex_unlock(&p->lock); 03723 return 0; 03724 }
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 3975 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.
03976 { 03977 struct sip_pvt *p = ast->tech_pvt; 03978 int res = 0; 03979 03980 ast_mutex_lock(&p->lock); 03981 switch(condition) { 03982 case AST_CONTROL_RINGING: 03983 if (ast->_state == AST_STATE_RING) { 03984 p->invitestate = INV_EARLY_MEDIA; 03985 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 03986 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 03987 /* Send 180 ringing if out-of-band seems reasonable */ 03988 transmit_response(p, "180 Ringing", &p->initreq); 03989 ast_set_flag(&p->flags[0], SIP_RINGING); 03990 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 03991 break; 03992 } else { 03993 /* Well, if it's not reasonable, just send in-band */ 03994 } 03995 } 03996 res = -1; 03997 break; 03998 case AST_CONTROL_BUSY: 03999 if (ast->_state != AST_STATE_UP) { 04000 transmit_response_reliable(p, "486 Busy Here", &p->initreq); 04001 p->invitestate = INV_COMPLETED; 04002 sip_alreadygone(p); 04003 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 04004 break; 04005 } 04006 res = -1; 04007 break; 04008 case AST_CONTROL_CONGESTION: 04009 if (ast->_state != AST_STATE_UP) { 04010 transmit_response_reliable(p, "503 Service Unavailable", &p->initreq); 04011 p->invitestate = INV_COMPLETED; 04012 sip_alreadygone(p); 04013 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 04014 break; 04015 } 04016 res = -1; 04017 break; 04018 case AST_CONTROL_PROCEEDING: 04019 if ((ast->_state != AST_STATE_UP) && 04020 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 04021 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 04022 transmit_response(p, "100 Trying", &p->initreq); 04023 p->invitestate = INV_PROCEEDING; 04024 break; 04025 } 04026 res = -1; 04027 break; 04028 case AST_CONTROL_PROGRESS: 04029 if ((ast->_state != AST_STATE_UP) && 04030 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 04031 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 04032 p->invitestate = INV_EARLY_MEDIA; 04033 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 04034 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 04035 break; 04036 } 04037 res = -1; 04038 break; 04039 case AST_CONTROL_HOLD: 04040 ast_rtp_new_source(p->rtp); 04041 ast_moh_start(ast, data, p->mohinterpret); 04042 break; 04043 case AST_CONTROL_UNHOLD: 04044 ast_rtp_new_source(p->rtp); 04045 ast_moh_stop(ast); 04046 break; 04047 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 04048 if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 04049 transmit_info_with_vidupdate(p); 04050 /* ast_rtcp_send_h261fur(p->vrtp); */ 04051 } else 04052 res = -1; 04053 break; 04054 case AST_CONTROL_SRCUPDATE: 04055 ast_rtp_new_source(p->rtp); 04056 break; 04057 case -1: 04058 res = -1; 04059 break; 04060 default: 04061 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 04062 res = -1; 04063 break; 04064 } 04065 ast_mutex_unlock(&p->lock); 04066 return res; 04067 }
static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 1775 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().
01776 { 01777 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT"; 01778 }
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 4075 of file chan_sip.c.
References accountcode, sip_pvt::accountcode, ast_channel::adsicpe, ast_channel::amaflags, sip_pvt::amaflags, append_history, AST_ADSI_UNAVAILABLE, ast_best_codec(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc(), ast_codec_choose(), ast_copy_string(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_features(), AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_fd(), ast_uri_decode(), ast_verbose(), sip_pvt::callgroup, ast_channel::callgroup, sip_pvt::callid, sip_pvt::callingpres, sip_pvt::capability, sip_pvt::chanvars, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, sip_pvt::cid_name, sip_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_channel::context, sip_pvt::context, sip_pvt::domain, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DTMF_DETECT, ast_channel::exten, sip_pvt::exten, f, ast_channel::fds, sip_pvt::flags, sip_pvt::from, sip_pvt::fromdomain, sip_pvt::fromname, sip_pvt::fromuser, sip_pvt::fullcontact, global_jbconf, sip_pvt::jointcapability, language, sip_pvt::language, sip_pvt::lock, LOG_DEBUG, ast_variable::name, ast_channel::nativeformats, ast_variable::next, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::peername, sip_pvt::pickupgroup, ast_channel::pickupgroup, sip_pvt::prefcodec, sip_pvt::prefs, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, sip_pvt::rdnis, ast_channel::readformat, ast_channel::rings, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_NO_HISTORY, sip_tech, sip_tech_info, SIPBUFSIZE, t38properties::state, sip_pvt::t38, T38_PEER_DIRECT, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::udptl, sip_pvt::uri, sip_pvt::useragent, sip_pvt::username, sip_pvt::vad, ast_variable::value, VERBOSE_PREFIX_3, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by handle_request_invite(), and sip_request_call().
04076 { 04077 struct ast_channel *tmp; 04078 struct ast_variable *v = NULL; 04079 int fmt; 04080 int what; 04081 int needvideo = 0, video = 0; 04082 char *decoded_exten; 04083 04084 if (option_debug != 0) { 04085 ast_verbose(VERBOSE_PREFIX_3 "NEW SIP CHANNEL, title: <%s>\n", title?title:"Null"); 04086 ast_verbose(VERBOSE_PREFIX_3 "from: %s\n", i->from); 04087 ast_verbose(VERBOSE_PREFIX_3 "username: <%s>\n", i->username); 04088 ast_verbose(VERBOSE_PREFIX_3 "peername: <%s>\n", i->peername); 04089 ast_verbose(VERBOSE_PREFIX_3 "fromdomain: %s\n", i->fromdomain); 04090 ast_verbose(VERBOSE_PREFIX_3 "fromuser: %s\n", i->fromuser); 04091 ast_verbose(VERBOSE_PREFIX_3 "fromname: %s\n", i->fromname); 04092 ast_verbose(VERBOSE_PREFIX_3 "fullcontact: %s\n", i->fullcontact); 04093 } 04094 04095 { 04096 char my_name[128]; /* pick a good name */ 04097 const char *f, *fromdomain = NULL; 04098 04099 if (!ast_strlen_zero(i->fromdomain) && strchr(i->fromdomain,':')) 04100 fromdomain = strchr(i->fromdomain,':') + 1; /* skip ':' */ 04101 else 04102 fromdomain = i->fromdomain; 04103 04104 if (!ast_strlen_zero(i->username)) { 04105 if (!ast_strlen_zero(title) && strcmp(i->username, title)) { 04106 /* title not empty and different from username */ 04107 snprintf(my_name, sizeof(my_name), "%s@%s", i->username, title); 04108 } else { 04109 /* username not empty, title is empty or equal to username */ 04110 snprintf(my_name, sizeof(my_name), "%s", i->username); 04111 } 04112 } else { /* username empty */ 04113 if (!ast_strlen_zero(i->peername)) { 04114 /* call from unregisted peer */ 04115 snprintf(my_name, sizeof(my_name), "%s", i->peername); 04116 } else { /* username and peername empty */ 04117 if (!ast_strlen_zero(title)) { /* title not empty */ 04118 snprintf(my_name, sizeof(my_name), "%s", title); 04119 } else if (!ast_strlen_zero(i->from)) { /* title empty, From: not empty */ 04120 f = i->from; 04121 if (!strncmp(f, "sip:", 4)) 04122 f += 4; 04123 snprintf(my_name, sizeof(my_name), "%s", f); 04124 } else { /* fallback to fromdomain */ 04125 snprintf(my_name, sizeof(my_name), "%s", fromdomain); 04126 } 04127 } 04128 } 04129 ast_mutex_unlock(&i->lock); 04130 /* Don't hold a sip pvt lock while we allocate a channel */ 04131 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); 04132 04133 } 04134 if (!tmp) { 04135 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 04136 ast_mutex_lock(&i->lock); 04137 return NULL; 04138 } 04139 ast_mutex_lock(&i->lock); 04140 04141 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO) 04142 tmp->tech = &sip_tech_info; 04143 else 04144 tmp->tech = &sip_tech; 04145 04146 /* Select our native format based on codec preference until we receive 04147 something from another device to the contrary. */ 04148 if (i->jointcapability) { /* The joint capabilities of us and peer */ 04149 what = i->jointcapability; 04150 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 04151 } else if (i->capability) { /* Our configured capability for this peer */ 04152 what = i->capability; 04153 video = i->capability & AST_FORMAT_VIDEO_MASK; 04154 } else { 04155 what = global_capability; /* Global codec support */ 04156 video = global_capability & AST_FORMAT_VIDEO_MASK; 04157 } 04158 04159 /* Set the native formats for audio and merge in video */ 04160 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video; 04161 if (option_debug > 2) { 04162 char buf[SIPBUFSIZE]; 04163 ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats)); 04164 ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability)); 04165 ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability)); 04166 ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1))); 04167 if (i->prefcodec) 04168 ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec)); 04169 } 04170 04171 /* XXX Why are we choosing a codec from the native formats?? */ 04172 fmt = ast_best_codec(tmp->nativeformats); 04173 04174 /* If we have a prefcodec setting, we have an inbound channel that set a 04175 preferred format for this call. Otherwise, we check the jointcapability 04176 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 04177 */ 04178 if (i->vrtp) { 04179 if (i->prefcodec) 04180 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 04181 else 04182 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 04183 } 04184 04185 if (option_debug > 2) { 04186 if (needvideo) 04187 ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n"); 04188 else 04189 ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n"); 04190 } 04191 04192 04193 04194 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 04195 i->vad = ast_dsp_new(); 04196 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 04197 if (global_relaxdtmf) 04198 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 04199 } 04200 if (i->rtp) { 04201 tmp->fds[0] = ast_rtp_fd(i->rtp); 04202 tmp->fds[1] = ast_rtcp_fd(i->rtp); 04203 } 04204 if (needvideo && i->vrtp) { 04205 tmp->fds[2] = ast_rtp_fd(i->vrtp); 04206 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 04207 } 04208 if (i->udptl) { 04209 tmp->fds[5] = ast_udptl_fd(i->udptl); 04210 } 04211 if (state == AST_STATE_RING) 04212 tmp->rings = 1; 04213 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 04214 tmp->writeformat = fmt; 04215 tmp->rawwriteformat = fmt; 04216 tmp->readformat = fmt; 04217 tmp->rawreadformat = fmt; 04218 tmp->tech_pvt = i; 04219 04220 tmp->callgroup = i->callgroup; 04221 tmp->pickupgroup = i->pickupgroup; 04222 tmp->cid.cid_pres = i->callingpres; 04223 if (!ast_strlen_zero(i->accountcode)) 04224 ast_string_field_set(tmp, accountcode, i->accountcode); 04225 if (i->amaflags) 04226 tmp->amaflags = i->amaflags; 04227 if (!ast_strlen_zero(i->language)) 04228 ast_string_field_set(tmp, language, i->language); 04229 i->owner = tmp; 04230 ast_module_ref(ast_module_info->self); 04231 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 04232 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 04233 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 04234 * structure so that there aren't issues when forming URI's 04235 */ 04236 decoded_exten = ast_strdupa(i->exten); 04237 ast_uri_decode(decoded_exten); 04238 ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten)); 04239 04240 /* Don't use ast_set_callerid() here because it will 04241 * generate an unnecessary NewCallerID event */ 04242 tmp->cid.cid_ani = ast_strdup(i->cid_num); 04243 if (!ast_strlen_zero(i->rdnis)) 04244 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 04245 04246 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 04247 tmp->cid.cid_dnid = ast_strdup(i->exten); 04248 04249 tmp->priority = 1; 04250 if (!ast_strlen_zero(i->uri)) 04251 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 04252 if (!ast_strlen_zero(i->domain)) 04253 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 04254 if (!ast_strlen_zero(i->useragent)) 04255 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 04256 if (!ast_strlen_zero(i->callid)) 04257 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 04258 if (i->rtp) 04259 ast_jb_configure(tmp, &global_jbconf); 04260 04261 /* If the INVITE contains T.38 SDP information set the proper channel variable so a created outgoing call will also have T.38 */ 04262 if (i->udptl && i->t38.state == T38_PEER_DIRECT) 04263 pbx_builtin_setvar_helper(tmp, "_T38CALL", "1"); 04264 04265 /* Set channel variables for this call from configuration */ 04266 for (v = i->chanvars ; v ; v = v->next) 04267 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04268 04269 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 04270 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04271 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 04272 ast_hangup(tmp); 04273 tmp = NULL; 04274 } 04275 04276 if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY)) 04277 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 04278 04279 return tmp; 04280 }
static int sip_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP Debugging in CLI.
Definition at line 11828 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11829 { 11830 if (argc != 4) 11831 return RESULT_SHOWUSAGE; 11832 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11833 ast_cli(fd, "SIP Debugging Disabled\n"); 11834 return RESULT_SUCCESS; 11835 }
static int sip_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11837 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11838 { 11839 if (argc != 3) 11840 return RESULT_SHOWUSAGE; 11841 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11842 ast_cli(fd, "SIP Debugging Disabled\n"); 11843 return RESULT_SUCCESS; 11844 }
static int sip_no_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP History logging (CLI).
Definition at line 11858 of file chan_sip.c.
References ast_cli(), FALSE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
11859 { 11860 if (argc != 3) { 11861 return RESULT_SHOWUSAGE; 11862 } 11863 recordhistory = FALSE; 11864 ast_cli(fd, "SIP History Recording Disabled\n"); 11865 return RESULT_SUCCESS; 11866 }
static int sip_notify | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Cli command to send SIP notify to peer.
Definition at line 11772 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.
11773 { 11774 struct ast_variable *varlist; 11775 int i; 11776 11777 if (argc < 4) 11778 return RESULT_SHOWUSAGE; 11779 11780 if (!notify_types) { 11781 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 11782 return RESULT_FAILURE; 11783 } 11784 11785 varlist = ast_variable_browse(notify_types, argv[2]); 11786 11787 if (!varlist) { 11788 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 11789 return RESULT_FAILURE; 11790 } 11791 11792 for (i = 3; i < argc; i++) { 11793 struct sip_pvt *p; 11794 struct sip_request req; 11795 struct ast_variable *var; 11796 11797 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { 11798 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 11799 return RESULT_FAILURE; 11800 } 11801 11802 if (create_addr(p, argv[i], NULL)) { 11803 /* Maybe they're not registered, etc. */ 11804 sip_destroy(p); 11805 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 11806 continue; 11807 } 11808 11809 initreqprep(&req, p, SIP_NOTIFY); 11810 11811 for (var = varlist; var; var = var->next) 11812 add_header(&req, var->name, ast_unescape_semicolon(var->value)); 11813 11814 /* Recalculate our side, and recalculate Call ID */ 11815 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 11816 p->ourip = __ourip; 11817 build_via(p); 11818 build_callid_pvt(p); 11819 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 11820 transmit_sip_request(p, &req); 11821 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11822 } 11823 11824 return RESULT_SUCCESS; 11825 }
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 13616 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().
13617 { 13618 struct sip_dual *d; 13619 struct ast_channel *transferee, *transferer; 13620 /* Chan2m: The transferer, chan1m: The transferee */ 13621 pthread_t th; 13622 13623 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 13624 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); 13625 if ((!transferer) || (!transferee)) { 13626 if (transferee) { 13627 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13628 ast_hangup(transferee); 13629 } 13630 if (transferer) { 13631 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13632 ast_hangup(transferer); 13633 } 13634 return -1; 13635 } 13636 13637 /* Make formats okay */ 13638 transferee->readformat = chan1->readformat; 13639 transferee->writeformat = chan1->writeformat; 13640 13641 /* Prepare for taking over the channel */ 13642 ast_channel_masquerade(transferee, chan1); 13643 13644 /* Setup the extensions and such */ 13645 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 13646 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 13647 transferee->priority = chan1->priority; 13648 13649 /* We make a clone of the peer channel too, so we can play 13650 back the announcement */ 13651 13652 /* Make formats okay */ 13653 transferer->readformat = chan2->readformat; 13654 transferer->writeformat = chan2->writeformat; 13655 13656 /* Prepare for taking over the channel. Go ahead and grab this channel 13657 * lock here to avoid a deadlock with callbacks into the channel driver 13658 * that hold the channel lock and want the pvt lock. */ 13659 while (ast_channel_trylock(chan2)) { 13660 struct sip_pvt *pvt = chan2->tech_pvt; 13661 DEADLOCK_AVOIDANCE(&pvt->lock); 13662 } 13663 ast_channel_masquerade(transferer, chan2); 13664 ast_channel_unlock(chan2); 13665 13666 /* Setup the extensions and such */ 13667 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 13668 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 13669 transferer->priority = chan2->priority; 13670 13671 ast_channel_lock(transferer); 13672 if (ast_do_masquerade(transferer)) { 13673 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 13674 ast_channel_unlock(transferer); 13675 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13676 ast_hangup(transferer); 13677 return -1; 13678 } 13679 ast_channel_unlock(transferer); 13680 if (!transferer || !transferee) { 13681 if (!transferer) { 13682 if (option_debug) 13683 ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n"); 13684 } 13685 if (!transferee) { 13686 if (option_debug) 13687 ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n"); 13688 } 13689 return -1; 13690 } 13691 if ((d = ast_calloc(1, sizeof(*d)))) { 13692 pthread_attr_t attr; 13693 13694 pthread_attr_init(&attr); 13695 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 13696 13697 /* Save original request for followup */ 13698 copy_request(&d->req, req); 13699 d->chan1 = transferee; /* Transferee */ 13700 d->chan2 = transferer; /* Transferer */ 13701 d->seqno = seqno; 13702 if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) { 13703 /* Could not start thread */ 13704 free(d); /* We don't need it anymore. If thread is created, d will be free'd 13705 by sip_park_thread() */ 13706 pthread_attr_destroy(&attr); 13707 return 0; 13708 } 13709 pthread_attr_destroy(&attr); 13710 } 13711 return -1; 13712 }
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 13549 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().
13550 { 13551 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 13552 struct sip_dual *d; 13553 struct sip_request req; 13554 int ext; 13555 int res; 13556 13557 d = stuff; 13558 transferee = d->chan1; 13559 transferer = d->chan2; 13560 copy_request(&req, &d->req); 13561 13562 if (!transferee || !transferer) { 13563 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 13564 return NULL; 13565 } 13566 if (option_debug > 3) 13567 ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 13568 13569 ast_channel_lock(transferee); 13570 if (ast_do_masquerade(transferee)) { 13571 ast_log(LOG_WARNING, "Masquerade failed.\n"); 13572 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 13573 ast_channel_unlock(transferee); 13574 return NULL; 13575 } 13576 ast_channel_unlock(transferee); 13577 13578 res = ast_park_call(transferee, transferer, 0, &ext); 13579 13580 13581 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 13582 if (!res) { 13583 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 13584 } else { 13585 /* Then tell the transferer what happened */ 13586 sprintf(buf, "Call parked on extension '%d'", ext); 13587 transmit_message_with_text(transferer->tech_pvt, buf); 13588 } 13589 #endif 13590 13591 /* Any way back to the current call??? */ 13592 /* Transmit response to the REFER request */ 13593 transmit_response(transferer->tech_pvt, "202 Accepted", &req); 13594 if (!res) { 13595 /* Transfer succeeded */ 13596 append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext); 13597 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 13598 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 13599 ast_hangup(transferer); /* This will cause a BYE */ 13600 if (option_debug) 13601 ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext); 13602 } else { 13603 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 13604 append_history(transferer->tech_pvt, "SIPpark","Parking failed\n"); 13605 if (option_debug) 13606 ast_log(LOG_DEBUG, "SIP Call parked failed \n"); 13607 /* Do not hangup call */ 13608 } 13609 free(d); 13610 return NULL; 13611 }
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 8853 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().
08854 { 08855 struct sip_peer *peer = find_peer(p->peername, NULL, 1, 0); 08856 08857 if (!peer) 08858 return; 08859 08860 /* If they put someone on hold, increment the value... otherwise decrement it */ 08861 if (hold) 08862 peer->onHold++; 08863 else 08864 peer->onHold--; 08865 08866 /* Request device state update */ 08867 ast_device_state_changed("SIP/%s", peer->name); 08868 08869 return; 08870 }
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 18831 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().
18832 { 18833 int ms = 0; 18834 18835 if (!speerobjs) /* No peers, just give up */ 18836 return; 18837 18838 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 18839 ASTOBJ_WRLOCK(iterator); 18840 if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) { 18841 struct sip_peer *peer_ptr = iterator; 18842 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 18843 } 18844 ms += 100; 18845 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, ASTOBJ_REF(iterator)); 18846 if (iterator->pokeexpire == -1) { 18847 struct sip_peer *peer_ptr = iterator; 18848 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 18849 } 18850 ASTOBJ_UNLOCK(iterator); 18851 } while (0) 18852 ); 18853 }
static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 16692 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_update_realtime(), ASTOBJ_UNREF, sip_peer::call, DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::name, sip_peer::pokeexpire, sched, sip_destroy(), sip_destroy_peer(), and sip_poke_peer_s().
Referenced by sip_poke_peer().
16693 { 16694 struct sip_peer *peer = (struct sip_peer *)data; 16695 16696 peer->pokeexpire = -1; 16697 if (peer->lastms > -1) { 16698 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 16699 ast_update_realtime("sippeers", "name", peer->name, "lastms", "-1", NULL); 16700 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 16701 } 16702 if (peer->call) 16703 sip_destroy(peer->call); 16704 peer->call = NULL; 16705 peer->lastms = -1; 16706 ast_device_state_changed("SIP/%s", peer->name); 16707 16708 /* This function gets called one place outside of the scheduler ... */ 16709 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16710 struct sip_peer *peer_ptr = peer; 16711 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16712 } 16713 16714 /* There is no need to ASTOBJ_REF() here. Just let the scheduled callback 16715 * inherit the reference that the current callback already has. */ 16716 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 16717 if (peer->pokeexpire == -1) { 16718 ASTOBJ_UNREF(peer, sip_destroy_peer); 16719 } 16720 16721 return 0; 16722 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 16727 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().
16728 { 16729 struct sip_pvt *p; 16730 int xmitres = 0; 16731 16732 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 16733 /* IF we have no IP, or this isn't to be monitored, return 16734 imeediately after clearing things out */ 16735 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16736 struct sip_peer *peer_ptr = peer; 16737 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16738 } 16739 peer->lastms = 0; 16740 peer->call = NULL; 16741 return 0; 16742 } 16743 if (peer->call) { 16744 if (sipdebug) 16745 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 16746 sip_destroy(peer->call); 16747 } 16748 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS))) 16749 return -1; 16750 16751 p->sa = peer->addr; 16752 p->recv = peer->addr; 16753 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 16754 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16755 16756 /* Send OPTIONs to peer's fullcontact */ 16757 if (!ast_strlen_zero(peer->fullcontact)) 16758 ast_string_field_set(p, fullcontact, peer->fullcontact); 16759 16760 if (!ast_strlen_zero(peer->tohost)) 16761 ast_string_field_set(p, tohost, peer->tohost); 16762 else 16763 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 16764 16765 /* Recalculate our side, and recalculate Call ID */ 16766 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16767 p->ourip = __ourip; 16768 build_via(p); 16769 build_callid_pvt(p); 16770 16771 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16772 struct sip_peer *peer_ptr = peer; 16773 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16774 } 16775 16776 p->relatedpeer = ASTOBJ_REF(peer); 16777 ast_set_flag(&p->flags[0], SIP_OUTGOING); 16778 #ifdef VOCAL_DATA_HACK 16779 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 16780 xmitres = transmit_invite(p, SIP_INVITE, 0, 2); 16781 #else 16782 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); 16783 #endif 16784 gettimeofday(&peer->ps, NULL); 16785 if (xmitres == XMIT_ERROR) { 16786 sip_poke_noanswer(ASTOBJ_REF(peer)); /* Immediately unreachable, network problems */ 16787 } else { 16788 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16789 struct sip_peer *peer_ptr = peer; 16790 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16791 } 16792 peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, ASTOBJ_REF(peer)); 16793 if (peer->pokeexpire == -1) { 16794 struct sip_peer *peer_ptr = peer; 16795 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16796 } 16797 } 16798 16799 return 0; 16800 }
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 8199 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().
08200 { 08201 struct sip_peer *peer = (struct sip_peer *) data; 08202 08203 peer->pokeexpire = -1; 08204 08205 sip_poke_peer(peer); 08206 08207 ASTOBJ_UNREF(peer, sip_destroy_peer); 08208 08209 return 0; 08210 }
static int sip_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 10552 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.
10553 { 10554 struct sip_peer *peer; 10555 struct sip_user *user; 10556 int pruneuser = FALSE; 10557 int prunepeer = FALSE; 10558 int multi = FALSE; 10559 char *name = NULL; 10560 regex_t regexbuf; 10561 10562 switch (argc) { 10563 case 4: 10564 if (!strcasecmp(argv[3], "user")) 10565 return RESULT_SHOWUSAGE; 10566 if (!strcasecmp(argv[3], "peer")) 10567 return RESULT_SHOWUSAGE; 10568 if (!strcasecmp(argv[3], "like")) 10569 return RESULT_SHOWUSAGE; 10570 if (!strcasecmp(argv[3], "all")) { 10571 multi = TRUE; 10572 pruneuser = prunepeer = TRUE; 10573 } else { 10574 pruneuser = prunepeer = TRUE; 10575 name = argv[3]; 10576 } 10577 break; 10578 case 5: 10579 if (!strcasecmp(argv[4], "like")) 10580 return RESULT_SHOWUSAGE; 10581 if (!strcasecmp(argv[3], "all")) 10582 return RESULT_SHOWUSAGE; 10583 if (!strcasecmp(argv[3], "like")) { 10584 multi = TRUE; 10585 name = argv[4]; 10586 pruneuser = prunepeer = TRUE; 10587 } else if (!strcasecmp(argv[3], "user")) { 10588 pruneuser = TRUE; 10589 if (!strcasecmp(argv[4], "all")) 10590 multi = TRUE; 10591 else 10592 name = argv[4]; 10593 } else if (!strcasecmp(argv[3], "peer")) { 10594 prunepeer = TRUE; 10595 if (!strcasecmp(argv[4], "all")) 10596 multi = TRUE; 10597 else 10598 name = argv[4]; 10599 } else 10600 return RESULT_SHOWUSAGE; 10601 break; 10602 case 6: 10603 if (strcasecmp(argv[4], "like")) 10604 return RESULT_SHOWUSAGE; 10605 if (!strcasecmp(argv[3], "user")) { 10606 pruneuser = TRUE; 10607 name = argv[5]; 10608 } else if (!strcasecmp(argv[3], "peer")) { 10609 prunepeer = TRUE; 10610 name = argv[5]; 10611 } else 10612 return RESULT_SHOWUSAGE; 10613 break; 10614 default: 10615 return RESULT_SHOWUSAGE; 10616 } 10617 10618 if (multi && name) { 10619 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 10620 return RESULT_SHOWUSAGE; 10621 } 10622 10623 if (multi) { 10624 if (prunepeer) { 10625 int pruned = 0; 10626 10627 ASTOBJ_CONTAINER_WRLOCK(&peerl); 10628 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10629 ASTOBJ_RDLOCK(iterator); 10630 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10631 ASTOBJ_UNLOCK(iterator); 10632 continue; 10633 }; 10634 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10635 ASTOBJ_MARK(iterator); 10636 pruned++; 10637 } 10638 ASTOBJ_UNLOCK(iterator); 10639 } while (0) ); 10640 if (pruned) { 10641 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 10642 ast_cli(fd, "%d peers pruned.\n", pruned); 10643 } else 10644 ast_cli(fd, "No peers found to prune.\n"); 10645 ASTOBJ_CONTAINER_UNLOCK(&peerl); 10646 } 10647 if (pruneuser) { 10648 int pruned = 0; 10649 10650 ASTOBJ_CONTAINER_WRLOCK(&userl); 10651 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10652 ASTOBJ_RDLOCK(iterator); 10653 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10654 ASTOBJ_UNLOCK(iterator); 10655 continue; 10656 }; 10657 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10658 ASTOBJ_MARK(iterator); 10659 pruned++; 10660 } 10661 ASTOBJ_UNLOCK(iterator); 10662 } while (0) ); 10663 if (pruned) { 10664 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 10665 ast_cli(fd, "%d users pruned.\n", pruned); 10666 } else 10667 ast_cli(fd, "No users found to prune.\n"); 10668 ASTOBJ_CONTAINER_UNLOCK(&userl); 10669 } 10670 } else { 10671 if (prunepeer) { 10672 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 10673 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10674 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 10675 ASTOBJ_CONTAINER_LINK(&peerl, peer); 10676 } else 10677 ast_cli(fd, "Peer '%s' pruned.\n", name); 10678 ASTOBJ_UNREF(peer, sip_destroy_peer); 10679 } else 10680 ast_cli(fd, "Peer '%s' not found.\n", name); 10681 } 10682 if (pruneuser) { 10683 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 10684 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10685 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 10686 ASTOBJ_CONTAINER_LINK(&userl, user); 10687 } else 10688 ast_cli(fd, "User '%s' pruned.\n", name); 10689 ASTOBJ_UNREF(user, sip_destroy_user); 10690 } else 10691 ast_cli(fd, "User '%s' not found.\n", name); 10692 } 10693 } 10694 10695 return RESULT_SUCCESS; 10696 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static] |
Read SIP RTP from channel.
Definition at line 4483 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().
04484 { 04485 struct ast_frame *fr; 04486 struct sip_pvt *p = ast->tech_pvt; 04487 int faxdetected = FALSE; 04488 04489 ast_mutex_lock(&p->lock); 04490 fr = sip_rtp_read(ast, p, &faxdetected); 04491 p->lastrtprx = time(NULL); 04492 04493 /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */ 04494 /* 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 */ 04495 if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) { 04496 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 04497 if (!p->pendinginvite) { 04498 if (option_debug > 2) 04499 ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name); 04500 p->t38.state = T38_LOCAL_REINVITE; 04501 transmit_reinvite_with_t38_sdp(p); 04502 if (option_debug > 1) 04503 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name); 04504 } 04505 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04506 if (option_debug > 2) 04507 ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name); 04508 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04509 } 04510 } 04511 04512 /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */ 04513 if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) { 04514 fr = &ast_null_frame; 04515 } 04516 04517 ast_mutex_unlock(&p->lock); 04518 return fr; 04519 }
static struct sockaddr_in * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static] |
The real destination address for a write.
Definition at line 1769 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().
01770 { 01771 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa; 01772 }
static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 8003 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().
08004 { 08005 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 08006 return p->refer ? 1 : 0; 08007 }
static int sip_reg_timeout | ( | const void * | data | ) | [static] |
Registration timeout, register again.
Definition at line 7740 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().
07741 { 07742 07743 /* if we are here, our registration timed out, so we'll just do it over */ 07744 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 07745 struct sip_pvt *p; 07746 int res; 07747 07748 /* if we couldn't get a reference to the registry object, punt */ 07749 if (!r) 07750 return 0; 07751 07752 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 07753 if (r->call) { 07754 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 07755 in the single SIP manager thread. */ 07756 p = r->call; 07757 ast_mutex_lock(&p->lock); 07758 if (p->registry) 07759 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 07760 r->call = NULL; 07761 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 07762 /* Pretend to ACK anything just in case */ 07763 __sip_pretend_ack(p); 07764 ast_mutex_unlock(&p->lock); 07765 } 07766 /* If we have a limit, stop registration and give up */ 07767 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 07768 /* Ok, enough is enough. Don't try any more */ 07769 /* We could add an external notification here... 07770 steal it from app_voicemail :-) */ 07771 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 07772 r->regstate = REG_STATE_FAILED; 07773 } else { 07774 r->regstate = REG_STATE_UNREGISTERED; 07775 r->timeout = -1; 07776 r->needdns = TRUE; 07777 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 07778 } 07779 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)); 07780 ASTOBJ_UNREF(r, sip_registry_destroy); 07781 return 0; 07782 }
static int sip_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 4814 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.
04815 { 04816 struct sip_registry *reg; 04817 int portnum = 0; 04818 char username[256] = ""; 04819 char *hostname=NULL, *secret=NULL, *authuser=NULL; 04820 char *porta=NULL; 04821 char *contact=NULL; 04822 04823 if (!value) 04824 return -1; 04825 ast_copy_string(username, value, sizeof(username)); 04826 /* First split around the last '@' then parse the two components. */ 04827 hostname = strrchr(username, '@'); /* allow @ in the first part */ 04828 if (hostname) 04829 *hostname++ = '\0'; 04830 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 04831 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 04832 return -1; 04833 } 04834 /* split user[:secret[:authuser]] */ 04835 secret = strchr(username, ':'); 04836 if (secret) { 04837 *secret++ = '\0'; 04838 authuser = strchr(secret, ':'); 04839 if (authuser) 04840 *authuser++ = '\0'; 04841 } 04842 /* split host[:port][/contact] */ 04843 contact = strchr(hostname, '/'); 04844 if (contact) 04845 *contact++ = '\0'; 04846 if (ast_strlen_zero(contact)) 04847 contact = "s"; 04848 porta = strchr(hostname, ':'); 04849 if (porta) { 04850 *porta++ = '\0'; 04851 portnum = atoi(porta); 04852 if (portnum == 0) { 04853 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 04854 return -1; 04855 } 04856 } 04857 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 04858 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 04859 return -1; 04860 } 04861 04862 if (ast_string_field_init(reg, 256)) { 04863 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 04864 free(reg); 04865 return -1; 04866 } 04867 04868 regobjs++; 04869 ASTOBJ_INIT(reg); 04870 ast_string_field_set(reg, contact, contact); 04871 if (!ast_strlen_zero(username)) 04872 ast_string_field_set(reg, username, username); 04873 if (hostname) 04874 ast_string_field_set(reg, hostname, hostname); 04875 if (authuser) 04876 ast_string_field_set(reg, authuser, authuser); 04877 if (secret) 04878 ast_string_field_set(reg, secret, secret); 04879 reg->expire = -1; 04880 reg->timeout = -1; 04881 reg->refresh = default_expiry; 04882 reg->portno = portnum; 04883 reg->callid_valid = FALSE; 04884 reg->ocseq = INITIAL_CSEQ; 04885 reg->needdns = TRUE; 04886 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 04887 ASTOBJ_UNREF(reg,sip_registry_destroy); 04888 return 0; 04889 }
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 3111 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().
03112 { 03113 /* Really delete */ 03114 if (option_debug > 2) 03115 ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 03116 03117 if (reg->call) { 03118 /* Clear registry before destroying to ensure 03119 we don't get reentered trying to grab the registry lock */ 03120 reg->call->registry = NULL; 03121 if (option_debug > 2) 03122 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 03123 sip_destroy(reg->call); 03124 } 03125 AST_SCHED_DEL(sched, reg->expire); 03126 AST_SCHED_DEL(sched, reg->timeout); 03127 ast_string_field_free_memory(reg); 03128 regobjs--; 03129 free(reg); 03130 03131 }
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 12502 of file chan_sip.c.
References ast_set_flag, sip_pvt::flags, SIP_NEEDREINVITE, and sip_pvt::waitid.
Referenced by handle_response_invite().
12503 { 12504 struct sip_pvt *p = (struct sip_pvt *) data; 12505 12506 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 12507 p->waitid = -1; 12508 return 0; 12509 }
static int sip_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Force reload of module from cli.
Definition at line 18899 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().
18900 { 18901 ast_mutex_lock(&sip_reload_lock); 18902 if (sip_reloading) 18903 ast_verbose("Previous SIP reload not yet done\n"); 18904 else { 18905 sip_reloading = TRUE; 18906 if (fd) 18907 sip_reloadreason = CHANNEL_CLI_RELOAD; 18908 else 18909 sip_reloadreason = CHANNEL_MODULE_RELOAD; 18910 } 18911 ast_mutex_unlock(&sip_reload_lock); 18912 restart_monitor(); 18913 18914 return 0; 18915 }
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 16912 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.
16913 { 16914 int oldformat; 16915 struct sip_pvt *p; 16916 struct ast_channel *tmpc = NULL; 16917 char *ext, *host; 16918 char tmp[256]; 16919 char *dest = data; 16920 16921 oldformat = format; 16922 if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { 16923 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)); 16924 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 16925 return NULL; 16926 } 16927 if (option_debug) 16928 ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 16929 16930 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { 16931 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data); 16932 *cause = AST_CAUSE_SWITCH_CONGESTION; 16933 return NULL; 16934 } 16935 16936 ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL); 16937 16938 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 16939 sip_destroy(p); 16940 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 16941 *cause = AST_CAUSE_SWITCH_CONGESTION; 16942 return NULL; 16943 } 16944 16945 ast_copy_string(tmp, dest, sizeof(tmp)); 16946 host = strchr(tmp, '@'); 16947 if (host) { 16948 *host++ = '\0'; 16949 ext = tmp; 16950 } else { 16951 ext = strchr(tmp, '/'); 16952 if (ext) 16953 *ext++ = '\0'; 16954 host = tmp; 16955 } 16956 16957 if (create_addr(p, host, NULL)) { 16958 *cause = AST_CAUSE_UNREGISTERED; 16959 if (option_debug > 2) 16960 ast_log(LOG_DEBUG, "Cant create SIP call - target device not registered\n"); 16961 sip_destroy(p); 16962 return NULL; 16963 } 16964 if (ast_strlen_zero(p->peername) && ext) 16965 ast_string_field_set(p, peername, ext); 16966 /* Recalculate our side, and recalculate Call ID */ 16967 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16968 p->ourip = __ourip; 16969 build_via(p); 16970 build_callid_pvt(p); 16971 16972 /* We have an extension to call, don't use the full contact here */ 16973 /* This to enable dialing registered peers with extension dialling, 16974 like SIP/peername/extension 16975 SIP/peername will still use the full contact */ 16976 if (ext) { 16977 ast_string_field_set(p, username, ext); 16978 ast_string_field_free(p, fullcontact); 16979 } 16980 #if 0 16981 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 16982 #endif 16983 p->prefcodec = oldformat; /* Format for this call */ 16984 ast_mutex_lock(&p->lock); 16985 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 16986 ast_mutex_unlock(&p->lock); 16987 if (!tmpc) 16988 sip_destroy(p); 16989 ast_update_use_count(); 16990 restart_monitor(); 16991 return tmpc; 16992 }
static int sip_reregister | ( | const void * | data | ) | [static] |
Update registration with SIP Proxy.
Definition at line 7708 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().
07709 { 07710 /* if we are here, we know that we need to reregister. */ 07711 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 07712 07713 /* if we couldn't get a reference to the registry object, punt */ 07714 if (!r) 07715 return 0; 07716 07717 if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 07718 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 07719 /* Since registry's are only added/removed by the the monitor thread, this 07720 may be overkill to reference/dereference at all here */ 07721 if (sipdebug) 07722 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 07723 07724 r->expire = -1; 07725 __sip_do_register(r); 07726 ASTOBJ_UNREF(r, sip_registry_destroy); 07727 return 0; 07728 }
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 4413 of file chan_sip.c.
References ast_dsp_process(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_null_frame, ast_rtcp_read(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_udptl_read(), f, ast_channel::fdno, sip_pvt::flags, sip_pvt::jointcapability, LOG_DEBUG, ast_channel::name, ast_channel::nativeformats, option_debug, sip_pvt::owner, ast_channel::readformat, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_PAGE2_T38SUPPORT_UDPTL, sip_pvt::t38, t38properties::t38support, sip_pvt::udptl, sip_pvt::vad, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by sip_read().
04414 { 04415 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 04416 struct ast_frame *f; 04417 04418 if (!p->rtp) { 04419 /* We have no RTP allocated for this channel */ 04420 return &ast_null_frame; 04421 } 04422 04423 switch(ast->fdno) { 04424 case 0: 04425 f = ast_rtp_read(p->rtp); /* RTP Audio */ 04426 break; 04427 case 1: 04428 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 04429 break; 04430 case 2: 04431 f = ast_rtp_read(p->vrtp); /* RTP Video */ 04432 break; 04433 case 3: 04434 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 04435 break; 04436 case 5: 04437 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 04438 break; 04439 default: 04440 f = &ast_null_frame; 04441 } 04442 /* Don't forward RFC2833 if we're not supposed to */ 04443 if (f && (f->frametype == AST_FRAME_DTMF) && 04444 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) 04445 return &ast_null_frame; 04446 04447 /* We already hold the channel lock */ 04448 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 04449 return f; 04450 04451 if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 04452 if (!(f->subclass & p->jointcapability)) { 04453 if (option_debug) { 04454 ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n", 04455 ast_getformatname(f->subclass), p->owner->name); 04456 } 04457 return &ast_null_frame; 04458 } 04459 if (option_debug) 04460 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 04461 p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; 04462 ast_set_read_format(p->owner, p->owner->readformat); 04463 ast_set_write_format(p->owner, p->owner->writeformat); 04464 } 04465 04466 if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 04467 f = ast_dsp_process(p->owner, p->vad, f); 04468 if (f && f->frametype == AST_FRAME_DTMF) { 04469 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') { 04470 if (option_debug) 04471 ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name); 04472 *faxdetect = 1; 04473 } else if (option_debug) { 04474 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 04475 } 04476 } 04477 } 04478 04479 return f; 04480 }
static void sip_scheddestroy | ( | struct sip_pvt * | p, | |
int | ms | |||
) | [static] |
Schedule destruction of SIP dialog.
Definition at line 2145 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().
02146 { 02147 if (ms < 0) { 02148 if (p->timer_t1 == 0) 02149 p->timer_t1 = 500; /* Set timer T1 if not set (RFC 3261) */ 02150 ms = p->timer_t1 * 64; 02151 } 02152 if (sip_debug_test_pvt(p)) 02153 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 02154 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 02155 append_history(p, "SchedDestroy", "%d ms", ms); 02156 02157 AST_SCHED_DEL(sched, p->autokillid); 02158 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 02159 }
static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 18856 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().
18857 { 18858 int ms; 18859 int regspacing; 18860 if (!regobjs) 18861 return; 18862 regspacing = default_expiry * 1000/regobjs; 18863 if (regspacing > 100) 18864 regspacing = 100; 18865 ms = regspacing; 18866 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 18867 ASTOBJ_WRLOCK(iterator); 18868 AST_SCHED_DEL(sched, iterator->expire); 18869 ms += regspacing; 18870 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 18871 ASTOBJ_UNLOCK(iterator); 18872 } while (0) 18873 ); 18874 }
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 16422 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().
16423 { 16424 /* Called with peerl lock, but releases it */ 16425 struct sip_pvt *p; 16426 int newmsgs, oldmsgs; 16427 16428 /* Do we have an IP address? If not, skip this peer */ 16429 if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 16430 return 0; 16431 16432 /* Check for messages */ 16433 ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs); 16434 16435 peer->lastmsgcheck = time(NULL); 16436 16437 /* Return now if it's the same thing we told them last time */ 16438 if (!force && ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) { 16439 return 0; 16440 } 16441 16442 16443 peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)); 16444 16445 if (peer->mwipvt) { 16446 /* Base message on subscription */ 16447 p = peer->mwipvt; 16448 } else { 16449 /* Build temporary dialog for this message */ 16450 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 16451 return -1; 16452 if (create_addr_from_peer(p, peer)) { 16453 /* Maybe they're not registered, etc. */ 16454 sip_destroy(p); 16455 return 0; 16456 } 16457 /* Recalculate our side, and recalculate Call ID */ 16458 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16459 p->ourip = __ourip; 16460 build_via(p); 16461 build_callid_pvt(p); 16462 /* Destroy this session after 32 secs */ 16463 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16464 } 16465 /* Send MWI */ 16466 ast_set_flag(&p->flags[0], SIP_OUTGOING); 16467 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 16468 return 0; 16469 }
static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 3906 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.
03907 { 03908 struct sip_pvt *p = ast->tech_pvt; 03909 int res = 0; 03910 03911 ast_mutex_lock(&p->lock); 03912 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03913 case SIP_DTMF_INBAND: 03914 res = -1; /* Tell Asterisk to generate inband indications */ 03915 break; 03916 case SIP_DTMF_RFC2833: 03917 if (p->rtp) 03918 ast_rtp_senddigit_begin(p->rtp, digit); 03919 break; 03920 default: 03921 break; 03922 } 03923 ast_mutex_unlock(&p->lock); 03924 03925 return res; 03926 }
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 3930 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().
03931 { 03932 struct sip_pvt *p = ast->tech_pvt; 03933 int res = 0; 03934 03935 ast_mutex_lock(&p->lock); 03936 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03937 case SIP_DTMF_INFO: 03938 transmit_info_with_digit(p, digit, duration); 03939 break; 03940 case SIP_DTMF_RFC2833: 03941 if (p->rtp) 03942 ast_rtp_senddigit_end(p->rtp, digit); 03943 break; 03944 case SIP_DTMF_INBAND: 03945 res = -1; /* Tell Asterisk to stop inband indications */ 03946 break; 03947 } 03948 ast_mutex_unlock(&p->lock); 03949 03950 return res; 03951 }
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 2405 of file chan_sip.c.
References ast_strlen_zero(), ast_verbose(), debug, ast_channel::name, sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().
02406 { 02407 struct sip_pvt *p = ast->tech_pvt; 02408 int debug = sip_debug_test_pvt(p); 02409 02410 if (debug) 02411 ast_verbose("Sending text %s on %s\n", text, ast->name); 02412 if (!p) 02413 return -1; 02414 if (ast_strlen_zero(text)) 02415 return 0; 02416 if (debug) 02417 ast_verbose("Really sending text %s on %s\n", text, ast->name); 02418 transmit_message_with_text(p, text); 02419 return 0; 02420 }
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 18583 of file chan_sip.c.
References ast_channel::_state, append_history, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_set_flag, AST_STATE_UP, ast_test_flag, sip_pvt::callid, sip_pvt::capability, sip_pvt::flags, sip_pvt::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, SIP_ALREADYGONE, SIP_CAN_REINVITE_NAT, SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), sip_pvt::vredirip, and sip_pvt::vrtp.
Referenced by sip_fixup().
18584 { 18585 struct sip_pvt *p; 18586 int changed = 0; 18587 18588 p = chan->tech_pvt; 18589 if (!p) 18590 return -1; 18591 18592 /* Disable early RTP bridge */ 18593 if (chan->_state != AST_STATE_UP && !global_directrtpsetup) /* We are in early state */ 18594 return 0; 18595 18596 ast_mutex_lock(&p->lock); 18597 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 18598 /* If we're destroyed, don't bother */ 18599 ast_mutex_unlock(&p->lock); 18600 return 0; 18601 } 18602 18603 /* if this peer cannot handle reinvites of the media stream to devices 18604 that are known to be behind a NAT, then stop the process now 18605 */ 18606 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 18607 ast_mutex_unlock(&p->lock); 18608 return 0; 18609 } 18610 18611 if (rtp) { 18612 changed |= ast_rtp_get_peer(rtp, &p->redirip); 18613 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 18614 memset(&p->redirip, 0, sizeof(p->redirip)); 18615 changed = 1; 18616 } 18617 if (vrtp) { 18618 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 18619 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 18620 memset(&p->vredirip, 0, sizeof(p->vredirip)); 18621 changed = 1; 18622 } 18623 if (codecs) { 18624 if ((p->redircodecs != codecs)) { 18625 p->redircodecs = codecs; 18626 changed = 1; 18627 } 18628 if ((p->capability & codecs) != p->capability) { 18629 p->jointcapability &= codecs; 18630 p->capability &= codecs; 18631 changed = 1; 18632 } 18633 } 18634 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 18635 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 18636 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 18637 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 18638 if (option_debug) 18639 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)); 18640 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 18641 if (option_debug > 2) { 18642 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)); 18643 } 18644 transmit_reinvite_with_sdp(p); 18645 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18646 if (option_debug > 2) { 18647 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)); 18648 } 18649 /* We have a pending Invite. Send re-invite when we're done with the invite */ 18650 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18651 } 18652 } 18653 /* Reset lastrtprx timer */ 18654 p->lastrtprx = p->lastrtptx = time(NULL); 18655 ast_mutex_unlock(&p->lock); 18656 return 0; 18657 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 18410 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.
18411 { 18412 struct sip_pvt *p; 18413 18414 p = chan->tech_pvt; 18415 if (!p) 18416 return -1; 18417 ast_mutex_lock(&p->lock); 18418 if (udptl) 18419 ast_udptl_get_peer(udptl, &p->udptlredirip); 18420 else 18421 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18422 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 18423 if (!p->pendinginvite) { 18424 if (option_debug > 2) { 18425 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); 18426 } 18427 transmit_reinvite_with_t38_sdp(p); 18428 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18429 if (option_debug > 2) { 18430 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); 18431 } 18432 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18433 } 18434 } 18435 /* Reset lastrtprx timer */ 18436 p->lastrtprx = p->lastrtptx = time(NULL); 18437 ast_mutex_unlock(&p->lock); 18438 return 0; 18439 }
static int sip_show_channel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show details of one active dialog.
Definition at line 11427 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.
11428 { 11429 struct sip_pvt *cur; 11430 size_t len; 11431 int found = 0; 11432 11433 if (argc != 4) 11434 return RESULT_SHOWUSAGE; 11435 len = strlen(argv[3]); 11436 ast_mutex_lock(&iflock); 11437 for (cur = iflist; cur; cur = cur->next) { 11438 if (!strncasecmp(cur->callid, argv[3], len)) { 11439 char formatbuf[SIPBUFSIZE/2]; 11440 ast_cli(fd,"\n"); 11441 if (cur->subscribed != NONE) 11442 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 11443 else 11444 ast_cli(fd, " * SIP Call\n"); 11445 ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 11446 ast_cli(fd, " Call-ID: %s\n", cur->callid); 11447 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 11448 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 11449 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 11450 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 11451 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 11452 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 11453 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 11454 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 11455 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 11456 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 11457 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 11458 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)" ); 11459 ast_cli(fd, " Our Tag: %s\n", cur->tag); 11460 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 11461 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 11462 if (!ast_strlen_zero(cur->username)) 11463 ast_cli(fd, " Username: %s\n", cur->username); 11464 if (!ast_strlen_zero(cur->peername)) 11465 ast_cli(fd, " Peername: %s\n", cur->peername); 11466 if (!ast_strlen_zero(cur->uri)) 11467 ast_cli(fd, " Original uri: %s\n", cur->uri); 11468 if (!ast_strlen_zero(cur->cid_num)) 11469 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 11470 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 11471 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 11472 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 11473 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 11474 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 11475 ast_cli(fd, " SIP Options: "); 11476 if (cur->sipoptions) { 11477 int x; 11478 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 11479 if (cur->sipoptions & sip_options[x].id) 11480 ast_cli(fd, "%s ", sip_options[x].text); 11481 } 11482 } else 11483 ast_cli(fd, "(none)\n"); 11484 ast_cli(fd, "\n\n"); 11485 found++; 11486 } 11487 } 11488 ast_mutex_unlock(&iflock); 11489 if (!found) 11490 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11491 return RESULT_SUCCESS; 11492 }
static int sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP channels.
Definition at line 11218 of file chan_sip.c.
References __sip_show_channels().
11219 { 11220 return __sip_show_channels(fd, argc, argv, 0); 11221 }
static int sip_show_domains | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list local domains.
Definition at line 10730 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.
10731 { 10732 struct domain *d; 10733 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 10734 10735 if (AST_LIST_EMPTY(&domain_list)) { 10736 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 10737 return RESULT_SUCCESS; 10738 } else { 10739 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 10740 AST_LIST_LOCK(&domain_list); 10741 AST_LIST_TRAVERSE(&domain_list, d, list) 10742 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 10743 domain_mode_to_text(d->mode)); 10744 AST_LIST_UNLOCK(&domain_list); 10745 ast_cli(fd, "\n"); 10746 return RESULT_SUCCESS; 10747 } 10748 }
static int sip_show_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show history details of one dialog.
Definition at line 11495 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.
11496 { 11497 struct sip_pvt *cur; 11498 size_t len; 11499 int found = 0; 11500 11501 if (argc != 4) 11502 return RESULT_SHOWUSAGE; 11503 if (!recordhistory) 11504 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 11505 len = strlen(argv[3]); 11506 ast_mutex_lock(&iflock); 11507 for (cur = iflist; cur; cur = cur->next) { 11508 if (!strncasecmp(cur->callid, argv[3], len)) { 11509 struct sip_history *hist; 11510 int x = 0; 11511 11512 ast_cli(fd,"\n"); 11513 if (cur->subscribed != NONE) 11514 ast_cli(fd, " * Subscription\n"); 11515 else 11516 ast_cli(fd, " * SIP Call\n"); 11517 if (cur->history) 11518 AST_LIST_TRAVERSE(cur->history, hist, list) 11519 ast_cli(fd, "%d. %s\n", ++x, hist->event); 11520 if (x == 0) 11521 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 11522 found++; 11523 } 11524 } 11525 ast_mutex_unlock(&iflock); 11526 if (!found) 11527 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11528 return RESULT_SUCCESS; 11529 }
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 10155 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.
10156 { 10157 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 10158 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 10159 char ilimits[40]; 10160 char iused[40]; 10161 int showall = FALSE; 10162 10163 if (argc < 3) 10164 return RESULT_SHOWUSAGE; 10165 10166 if (argc == 4 && !strcmp(argv[3],"all")) 10167 showall = TRUE; 10168 10169 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 10170 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10171 ASTOBJ_RDLOCK(iterator); 10172 if (iterator->call_limit) 10173 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 10174 else 10175 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 10176 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 10177 if (showall || iterator->call_limit) 10178 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 10179 ASTOBJ_UNLOCK(iterator); 10180 } while (0) ); 10181 10182 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 10183 10184 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10185 ASTOBJ_RDLOCK(iterator); 10186 if (iterator->call_limit) 10187 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 10188 else 10189 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 10190 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 10191 if (showall || iterator->call_limit) 10192 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 10193 ASTOBJ_UNLOCK(iterator); 10194 } while (0) ); 10195 10196 return RESULT_SUCCESS; 10197 #undef FORMAT 10198 #undef FORMAT2 10199 }
static int sip_show_objects | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 10476 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
10477 { 10478 char tmp[256]; 10479 if (argc != 3) 10480 return RESULT_SHOWUSAGE; 10481 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 10482 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 10483 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 10484 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 10485 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 10486 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 10487 return RESULT_SUCCESS; 10488 }
static int sip_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 10782 of file chan_sip.c.
References _sip_show_peer().
10783 { 10784 return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); 10785 }
static int sip_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Show Peers command.
Definition at line 10332 of file chan_sip.c.
References _sip_show_peers().
10333 { 10334 return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); 10335 }
static int sip_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 11055 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.
11056 { 11057 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 11058 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 11059 char host[80]; 11060 char tmpdat[256]; 11061 struct tm tm; 11062 11063 11064 if (argc != 3) 11065 return RESULT_SHOWUSAGE; 11066 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 11067 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 11068 ASTOBJ_RDLOCK(iterator); 11069 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 11070 if (iterator->regtime) { 11071 ast_localtime(&iterator->regtime, &tm, NULL); 11072 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 11073 } else { 11074 tmpdat[0] = 0; 11075 } 11076 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 11077 ASTOBJ_UNLOCK(iterator); 11078 } while(0)); 11079 return RESULT_SUCCESS; 11080 #undef FORMAT 11081 #undef FORMAT2 11082 }
static int sip_show_settings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List global settings for the SIP channel.
Definition at line 11085 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().
11086 { 11087 int realtimepeers; 11088 int realtimeusers; 11089 char codec_buf[SIPBUFSIZE]; 11090 11091 realtimepeers = ast_check_realtime("sippeers"); 11092 realtimeusers = ast_check_realtime("sipusers"); 11093 11094 if (argc != 3) 11095 return RESULT_SHOWUSAGE; 11096 ast_cli(fd, "\n\nGlobal Settings:\n"); 11097 ast_cli(fd, "----------------\n"); 11098 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 11099 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 11100 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 11101 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 11102 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 11103 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 11104 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 11105 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 11106 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 11107 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 11108 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 11109 ast_cli(fd, " Our auth realm %s\n", global_realm); 11110 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 11111 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 11112 ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No"); 11113 ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No"); 11114 ast_cli(fd, " User Agent: %s\n", global_useragent); 11115 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 11116 ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 11117 ast_cli(fd, " Caller ID: %s\n", default_callerid); 11118 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 11119 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 11120 ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 11121 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 11122 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 11123 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 11124 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 11125 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 11126 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 11127 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 11128 #endif 11129 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 11130 if (!realtimepeers && !realtimeusers) 11131 ast_cli(fd, " SIP realtime: Disabled\n" ); 11132 else 11133 ast_cli(fd, " SIP realtime: Enabled\n" ); 11134 11135 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 11136 ast_cli(fd, "---------------------------\n"); 11137 ast_cli(fd, " Codecs: "); 11138 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 11139 ast_cli(fd, "%s\n", codec_buf); 11140 ast_cli(fd, " Codec Order: "); 11141 print_codec_to_cli(fd, &default_prefs); 11142 ast_cli(fd, "\n"); 11143 ast_cli(fd, " T1 minimum: %d\n", global_t1min); 11144 ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No"); 11145 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 11146 ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 11147 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 11148 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 11149 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 11150 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 11151 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 11152 ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); 11153 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 11154 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 11155 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 11156 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 11157 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 11158 ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No"); 11159 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 11160 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate); 11161 ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No"); 11162 ast_cli(fd, "\nDefault Settings:\n"); 11163 ast_cli(fd, "-----------------\n"); 11164 ast_cli(fd, " Context: %s\n", default_context); 11165 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 11166 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 11167 ast_cli(fd, " Qualify: %d\n", default_qualify); 11168 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 11169 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" ); 11170 ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)")); 11171 ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); 11172 ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); 11173 ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); 11174 11175 11176 if (realtimepeers || realtimeusers) { 11177 ast_cli(fd, "\nRealtime SIP Settings:\n"); 11178 ast_cli(fd, "----------------------\n"); 11179 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 11180 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 11181 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 11182 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 11183 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 11184 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 11185 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 11186 } 11187 ast_cli(fd, "\n----\n"); 11188 return RESULT_SUCCESS; 11189 }
static int sip_show_subscriptions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP subscriptions.
Definition at line 11224 of file chan_sip.c.
References __sip_show_channels().
11225 { 11226 return __sip_show_channels(fd, argc, argv, 1); 11227 }
static int sip_show_user | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one user in detail.
Definition at line 11000 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.
11001 { 11002 char cbuf[256]; 11003 struct sip_user *user; 11004 struct ast_variable *v; 11005 int load_realtime; 11006 11007 if (argc < 4) 11008 return RESULT_SHOWUSAGE; 11009 11010 /* Load from realtime storage? */ 11011 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 11012 11013 user = find_user(argv[3], load_realtime); 11014 if (user) { 11015 ast_cli(fd,"\n\n"); 11016 ast_cli(fd, " * Name : %s\n", user->name); 11017 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 11018 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 11019 ast_cli(fd, " Context : %s\n", user->context); 11020 ast_cli(fd, " Language : %s\n", user->language); 11021 if (!ast_strlen_zero(user->accountcode)) 11022 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 11023 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 11024 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 11025 ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 11026 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 11027 ast_cli(fd, " Call limit : %d\n", user->call_limit); 11028 ast_cli(fd, " Callgroup : "); 11029 print_group(fd, user->callgroup, 0); 11030 ast_cli(fd, " Pickupgroup : "); 11031 print_group(fd, user->pickupgroup, 0); 11032 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 11033 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 11034 ast_cli(fd, " Codec Order : ("); 11035 print_codec_to_cli(fd, &user->prefs); 11036 ast_cli(fd, ")\n"); 11037 11038 ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No"); 11039 if (user->chanvars) { 11040 ast_cli(fd, " Variables :\n"); 11041 for (v = user->chanvars ; v ; v = v->next) 11042 ast_cli(fd, " %s = %s\n", v->name, v->value); 11043 } 11044 ast_cli(fd,"\n"); 11045 ASTOBJ_UNREF(user,sip_destroy_user); 11046 } else { 11047 ast_cli(fd,"User %s not found.\n", argv[3]); 11048 ast_cli(fd,"\n"); 11049 } 11050 11051 return RESULT_SUCCESS; 11052 }
static int sip_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 10255 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.
10256 { 10257 regex_t regexbuf; 10258 int havepattern = FALSE; 10259 10260 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 10261 10262 switch (argc) { 10263 case 5: 10264 if (!strcasecmp(argv[3], "like")) { 10265 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 10266 return RESULT_SHOWUSAGE; 10267 havepattern = TRUE; 10268 } else 10269 return RESULT_SHOWUSAGE; 10270 case 3: 10271 break; 10272 default: 10273 return RESULT_SHOWUSAGE; 10274 } 10275 10276 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 10277 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10278 ASTOBJ_RDLOCK(iterator); 10279 10280 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10281 ASTOBJ_UNLOCK(iterator); 10282 continue; 10283 } 10284 10285 ast_cli(fd, FORMAT, iterator->name, 10286 iterator->secret, 10287 iterator->accountcode, 10288 iterator->context, 10289 iterator->ha ? "Yes" : "No", 10290 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 10291 ASTOBJ_UNLOCK(iterator); 10292 } while (0) 10293 ); 10294 10295 if (havepattern) 10296 regfree(®exbuf); 10297 10298 return RESULT_SUCCESS; 10299 #undef FORMAT 10300 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 18770 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().
18771 { 18772 char *cdest; 18773 char *extension, *host, *port; 18774 char tmp[80]; 18775 18776 cdest = ast_strdupa(dest); 18777 18778 extension = strsep(&cdest, "@"); 18779 host = strsep(&cdest, ":"); 18780 port = strsep(&cdest, ":"); 18781 if (ast_strlen_zero(extension)) { 18782 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 18783 return 0; 18784 } 18785 18786 /* we'll issue the redirect message here */ 18787 if (!host) { 18788 char *localtmp; 18789 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 18790 if (ast_strlen_zero(tmp)) { 18791 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 18792 return 0; 18793 } 18794 if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 18795 char lhost[80], lport[80]; 18796 memset(lhost, 0, sizeof(lhost)); 18797 memset(lport, 0, sizeof(lport)); 18798 localtmp++; 18799 /* This is okey because lhost and lport are as big as tmp */ 18800 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 18801 if (ast_strlen_zero(lhost)) { 18802 ast_log(LOG_ERROR, "Can't find the host address\n"); 18803 return 0; 18804 } 18805 host = ast_strdupa(lhost); 18806 if (!ast_strlen_zero(lport)) { 18807 port = ast_strdupa(lport); 18808 } 18809 } 18810 } 18811 18812 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 18813 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 18814 18815 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 18816 sip_alreadygone(p); 18817 return 0; 18818 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
Transfer SIP call.
Definition at line 3954 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().
03955 { 03956 struct sip_pvt *p = ast->tech_pvt; 03957 int res; 03958 03959 if (dest == NULL) /* functions below do not take a NULL */ 03960 dest = ""; 03961 ast_mutex_lock(&p->lock); 03962 if (ast->_state == AST_STATE_RING) 03963 res = sip_sipredirect(p, dest); 03964 else 03965 res = transmit_refer(p, dest); 03966 ast_mutex_unlock(&p->lock); 03967 return res; 03968 }
static int sip_uri_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
Definition at line 14353 of file chan_sip.c.
References ast_strdupa, S_OR, sip_uri_headers_cmp(), and sip_uri_params_cmp().
Referenced by handle_request_invite().
14354 { 14355 char *uri1 = ast_strdupa(input1); 14356 char *uri2 = ast_strdupa(input2); 14357 char *host1; 14358 char *host2; 14359 char *params1; 14360 char *params2; 14361 char *headers1; 14362 char *headers2; 14363 14364 /* Strip off "sip:" from the URI. We know this is present 14365 * because it was checked back in parse_request() 14366 */ 14367 strsep(&uri1, ":"); 14368 strsep(&uri2, ":"); 14369 14370 if ((host1 = strchr(uri1, '@'))) { 14371 *host1++ = '\0'; 14372 } 14373 if ((host2 = strchr(uri2, '@'))) { 14374 *host2++ = '\0'; 14375 } 14376 14377 /* Check for mismatched username and passwords. This is the 14378 * only case-sensitive comparison of a SIP URI 14379 */ 14380 if ((host1 && !host2) || 14381 (host2 && !host1) || 14382 (host1 && host2 && strcmp(uri1, uri2))) { 14383 return 1; 14384 } 14385 14386 if (!host1) 14387 host1 = uri1; 14388 if (!host2) 14389 host2 = uri2; 14390 14391 /* Strip off the parameters and headers so we can compare 14392 * host and port 14393 */ 14394 14395 if ((params1 = strchr(host1, ';'))) { 14396 *params1++ = '\0'; 14397 } 14398 if ((params2 = strchr(host2, ';'))) { 14399 *params2++ = '\0'; 14400 } 14401 14402 /* Headers come after parameters, but there may be headers without 14403 * parameters, thus the S_OR 14404 */ 14405 if ((headers1 = strchr(S_OR(params1, host1), '?'))) { 14406 *headers1++ = '\0'; 14407 } 14408 if ((headers2 = strchr(S_OR(params2, host2), '?'))) { 14409 *headers2++ = '\0'; 14410 } 14411 14412 /* Now the host/port are properly isolated. We can get by with a string comparison 14413 * because the SIP URI checking rules have some interesting exceptions that make 14414 * this possible. I will note 2 in particular 14415 * 1. hostnames which resolve to the same IP address as well as a hostname and its 14416 * IP address are not considered a match with SIP URI's. 14417 * 2. If one URI specifies a port and the other does not, then the URIs do not match. 14418 * This includes if one URI explicitly contains port 5060 and the other implies it 14419 * by not having a port specified. 14420 */ 14421 14422 if (strcasecmp(host1, host2)) { 14423 return 1; 14424 } 14425 14426 /* Headers have easier rules to follow, so do those first */ 14427 if (sip_uri_headers_cmp(headers1, headers2)) { 14428 return 1; 14429 } 14430 14431 /* And now the parameters. Ugh */ 14432 return sip_uri_params_cmp(params1, params2); 14433 }
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 14307 of file chan_sip.c.
References ast_strdupa, and ast_strlen_zero().
Referenced by sip_uri_cmp().
14308 { 14309 char *headers1 = NULL; 14310 char *headers2 = NULL; 14311 int zerolength1 = 0; 14312 int zerolength2 = 0; 14313 int different = 0; 14314 char *header1; 14315 14316 if (ast_strlen_zero(input1)) { 14317 zerolength1 = 1; 14318 } else { 14319 headers1 = ast_strdupa(input1); 14320 } 14321 14322 if (ast_strlen_zero(input2)) { 14323 zerolength2 = 1; 14324 } else { 14325 headers2 = ast_strdupa(input2); 14326 } 14327 14328 if ((zerolength1 && !zerolength2) || 14329 (zerolength2 && !zerolength1)) 14330 return 1; 14331 14332 if (zerolength1 && zerolength2) 14333 return 0; 14334 14335 /* At this point, we can definitively state that both inputs are 14336 * not zero-length. First, one more optimization. If the length 14337 * of the headers is not equal, then we definitely have no match 14338 */ 14339 if (strlen(headers1) != strlen(headers2)) { 14340 return 1; 14341 } 14342 14343 for (header1 = strsep(&headers1, "&"); header1; header1 = strsep(&headers1, "&")) { 14344 if (!strcasestr(headers2, header1)) { 14345 different = 1; 14346 break; 14347 } 14348 } 14349 14350 return different; 14351 }
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 14167 of file chan_sip.c.
References ast_strdupa, and ast_strlen_zero().
Referenced by sip_uri_cmp().
14168 { 14169 char *params1 = NULL; 14170 char *params2 = NULL; 14171 char *pos1; 14172 char *pos2; 14173 int zerolength1 = 0; 14174 int zerolength2 = 0; 14175 int maddrmatch = 0; 14176 int ttlmatch = 0; 14177 int usermatch = 0; 14178 int methodmatch = 0; 14179 14180 if (ast_strlen_zero(input1)) { 14181 zerolength1 = 1; 14182 } else { 14183 params1 = ast_strdupa(input1); 14184 } 14185 if (ast_strlen_zero(input2)) { 14186 zerolength2 = 1; 14187 } else { 14188 params2 = ast_strdupa(input2); 14189 } 14190 14191 /*Quick optimization. If both params are zero-length, then 14192 * they match 14193 */ 14194 if (zerolength1 && zerolength2) { 14195 return 0; 14196 } 14197 14198 pos1 = params1; 14199 while (!ast_strlen_zero(pos1)) { 14200 char *name1 = pos1; 14201 char *value1 = strchr(pos1, '='); 14202 char *semicolon1 = strchr(pos1, ';'); 14203 int matched = 0; 14204 if (semicolon1) { 14205 *semicolon1++ = '\0'; 14206 } 14207 if (!value1) { 14208 goto fail; 14209 } 14210 *value1++ = '\0'; 14211 /* Checkpoint reached. We have the name and value parsed for param1 14212 * We have to duplicate params2 each time through the second loop 14213 * or else we can't search and replace the semicolons with \0 each 14214 * time 14215 */ 14216 pos2 = ast_strdupa(params2); 14217 while (!ast_strlen_zero(pos2)) { 14218 char *name2 = pos2; 14219 char *value2 = strchr(pos2, '='); 14220 char *semicolon2 = strchr(pos2, ';'); 14221 if (semicolon2) { 14222 *semicolon2++ = '\0'; 14223 } 14224 if (!value2) { 14225 goto fail; 14226 } 14227 *value2++ = '\0'; 14228 if (!strcasecmp(name1, name2)) { 14229 if (strcasecmp(value1, value2)) { 14230 goto fail; 14231 } else { 14232 matched = 1; 14233 break; 14234 } 14235 } 14236 pos2 = semicolon2; 14237 } 14238 /* Need to see if the parameter we're looking at is one of the 'must-match' parameters */ 14239 if (!strcasecmp(name1, "maddr")) { 14240 if (matched) { 14241 maddrmatch = 1; 14242 } else { 14243 goto fail; 14244 } 14245 } else if (!strcasecmp(name1, "ttl")) { 14246 if (matched) { 14247 ttlmatch = 1; 14248 } else { 14249 goto fail; 14250 } 14251 } else if (!strcasecmp(name1, "user")) { 14252 if (matched) { 14253 usermatch = 1; 14254 } else { 14255 goto fail; 14256 } 14257 } else if (!strcasecmp(name1, "method")) { 14258 if (matched) { 14259 methodmatch = 1; 14260 } else { 14261 goto fail; 14262 } 14263 } 14264 pos1 = semicolon1; 14265 } 14266 14267 /* We've made it out of that horrible O(m*n) construct and there are no 14268 * failures yet. We're not done yet, though, because params2 could have 14269 * an maddr, ttl, user, or method header and params1 did not. 14270 */ 14271 pos2 = params2; 14272 while (!ast_strlen_zero(pos2)) { 14273 char *name2 = pos2; 14274 char *value2 = strchr(pos2, '='); 14275 char *semicolon2 = strchr(pos2, ';'); 14276 if (semicolon2) { 14277 *semicolon2++ = '\0'; 14278 } 14279 if (!value2) { 14280 goto fail; 14281 } 14282 *value2++ = '\0'; 14283 if ((!strcasecmp(name2, "maddr") && !maddrmatch) || 14284 (!strcasecmp(name2, "ttl") && !ttlmatch) || 14285 (!strcasecmp(name2, "user") && !usermatch) || 14286 (!strcasecmp(name2, "method") && !methodmatch)) { 14287 goto fail; 14288 } 14289 } 14290 return 0; 14291 14292 fail: 14293 return 1; 14294 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 3779 of file chan_sip.c.
References ast_channel::_state, AST_FORMAT_AUDIO_MASK, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_new_source(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), sip_pvt::flags, ast_frame::frametype, sip_pvt::initreq, INV_EARLY_MEDIA, sip_pvt::invitestate, sip_pvt::lastrtptx, sip_pvt::lock, ast_channel::nativeformats, ast_channel::readformat, sip_pvt::rtp, SIP_OUTGOING, SIP_PROGRESS_SENT, ast_frame::subclass, ast_channel::tech_pvt, transmit_response_with_sdp(), sip_pvt::udptl, sip_pvt::vrtp, ast_channel::writeformat, and XMIT_UNRELIABLE.
03780 { 03781 struct sip_pvt *p = ast->tech_pvt; 03782 int res = 0; 03783 03784 switch (frame->frametype) { 03785 case AST_FRAME_VOICE: 03786 if (!(frame->subclass & ast->nativeformats)) { 03787 char s1[512], s2[512], s3[512]; 03788 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n", 03789 frame->subclass, 03790 ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK), 03791 ast->nativeformats & AST_FORMAT_AUDIO_MASK, 03792 ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat), 03793 ast->readformat, 03794 ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat), 03795 ast->writeformat); 03796 return 0; 03797 } 03798 if (p) { 03799 ast_mutex_lock(&p->lock); 03800 if (p->rtp) { 03801 /* If channel is not up, activate early media session */ 03802 if ((ast->_state != AST_STATE_UP) && 03803 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03804 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03805 ast_rtp_new_source(p->rtp); 03806 p->invitestate = INV_EARLY_MEDIA; 03807 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03808 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03809 } 03810 p->lastrtptx = time(NULL); 03811 res = ast_rtp_write(p->rtp, frame); 03812 } 03813 ast_mutex_unlock(&p->lock); 03814 } 03815 break; 03816 case AST_FRAME_VIDEO: 03817 if (p) { 03818 ast_mutex_lock(&p->lock); 03819 if (p->vrtp) { 03820 /* Activate video early media */ 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 p->invitestate = INV_EARLY_MEDIA; 03825 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03826 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03827 } 03828 p->lastrtptx = time(NULL); 03829 res = ast_rtp_write(p->vrtp, frame); 03830 } 03831 ast_mutex_unlock(&p->lock); 03832 } 03833 break; 03834 case AST_FRAME_IMAGE: 03835 return 0; 03836 break; 03837 case AST_FRAME_MODEM: 03838 if (p) { 03839 ast_mutex_lock(&p->lock); 03840 /* UDPTL requires two-way communication, so early media is not needed here. 03841 we simply forget the frames if we get modem frames before the bridge is up. 03842 Fax will re-transmit. 03843 */ 03844 if (p->udptl && ast->_state == AST_STATE_UP) 03845 res = ast_udptl_write(p->udptl, frame); 03846 ast_mutex_unlock(&p->lock); 03847 } 03848 break; 03849 default: 03850 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 03851 return 0; 03852 } 03853 03854 return res; 03855 }
static int sipsock_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Read data from SIP socket.
Definition at line 16302 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().
16303 { 16304 struct sip_request req; 16305 struct sockaddr_in sin = { 0, }; 16306 struct sip_pvt *p; 16307 int res; 16308 socklen_t len = sizeof(sin); 16309 int nounlock = 0; 16310 int recount = 0; 16311 int lockretry; 16312 16313 memset(&req, 0, sizeof(req)); 16314 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 16315 if (res < 0) { 16316 #if !defined(__FreeBSD__) 16317 if (errno == EAGAIN) 16318 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 16319 else 16320 #endif 16321 if (errno != ECONNREFUSED) 16322 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 16323 return 1; 16324 } 16325 if (option_debug && res == sizeof(req.data) - 1) 16326 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 16327 16328 req.data[res] = '\0'; 16329 req.len = res; 16330 if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */ 16331 ast_set_flag(&req, SIP_PKT_DEBUG); 16332 if (pedanticsipchecking) 16333 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 16334 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 16335 ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data); 16336 16337 if(parse_request(&req) == -1) /* Bad packet, can't parse */ 16338 return 1; 16339 16340 req.method = find_sip_method(req.rlPart1); 16341 16342 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 16343 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 16344 16345 if (req.headers < 2) /* Must have at least two headers */ 16346 return 1; 16347 16348 /* Process request, with netlock held, and with usual deadlock avoidance */ 16349 for (lockretry = 10; lockretry > 0; lockretry--) { 16350 ast_mutex_lock(&netlock); 16351 16352 /* Find the active SIP dialog or create a new one */ 16353 p = find_call(&req, &sin, req.method); /* returns p locked */ 16354 if (p == NULL) { 16355 if (option_debug) 16356 ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len); 16357 ast_mutex_unlock(&netlock); 16358 return 1; 16359 } 16360 /* Go ahead and lock the owner if it has one -- we may need it */ 16361 /* because this is deadlock-prone, we need to try and unlock if failed */ 16362 if (!p->owner || !ast_channel_trylock(p->owner)) 16363 break; /* locking succeeded */ 16364 if (lockretry != 1) { 16365 ast_mutex_unlock(&p->lock); 16366 ast_mutex_unlock(&netlock); 16367 /* Sleep for a very short amount of time */ 16368 usleep(1); 16369 } 16370 } 16371 p->recv = sin; 16372 16373 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */ 16374 append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2); 16375 16376 if (!lockretry) { 16377 if (!queue_request(p, &req)) { 16378 /* the request has been queued for later handling */ 16379 ast_mutex_unlock(&p->lock); 16380 ast_mutex_unlock(&netlock); 16381 return 1; 16382 } 16383 16384 /* This is unsafe, since p->owner is not locked. */ 16385 if (p->owner) 16386 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 ??? - ")); 16387 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 16388 if (req.method != SIP_ACK) 16389 transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */ 16390 /* XXX We could add retry-after to make sure they come back */ 16391 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 16392 ast_mutex_unlock(&p->lock); 16393 ast_mutex_unlock(&netlock); 16394 return 1; 16395 } 16396 16397 /* if there are queued requests on this sip_pvt, process them first, so that everything is 16398 handled in order 16399 */ 16400 if (!AST_LIST_EMPTY(&p->request_queue)) { 16401 AST_SCHED_DEL(sched, p->request_queue_sched_id); 16402 process_request_queue(p, &recount, &nounlock); 16403 } 16404 16405 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 16406 /* Request failed */ 16407 if (option_debug) 16408 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 16409 } 16410 16411 if (p->owner && !nounlock) 16412 ast_channel_unlock(p->owner); 16413 ast_mutex_unlock(&p->lock); 16414 ast_mutex_unlock(&netlock); 16415 if (recount) 16416 ast_update_use_count(); 16417 16418 return 1; 16419 }
static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 13092 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().
13093 { 13094 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 13095 if (p->rtp) 13096 ast_rtp_stop(p->rtp); 13097 if (p->vrtp) 13098 ast_rtp_stop(p->vrtp); 13099 if (p->udptl) 13100 ast_udptl_stop(p->udptl); 13101 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 11192 of file chan_sip.c.
References subscription_types, and type.
Referenced by sip_show_channel().
11193 { 11194 int i; 11195 11196 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 11197 if (subscription_types[i].type == subtype) { 11198 return subscription_types[i].text; 11199 } 11200 } 11201 return subscription_types[0].text; 11202 }
static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 6514 of file chan_sip.c.
References ast_log(), LOG_DEBUG, option_debug, T38FAX_RATE_12000, T38FAX_RATE_14400, T38FAX_RATE_2400, T38FAX_RATE_4800, T38FAX_RATE_7200, and T38FAX_RATE_9600.
Referenced by add_t38_sdp().
06515 { 06516 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 06517 06518 if (maxrate & T38FAX_RATE_14400) { 06519 if (option_debug > 1) 06520 ast_log(LOG_DEBUG, "T38MaxBitRate 14400 found\n"); 06521 return 14400; 06522 } else if (maxrate & T38FAX_RATE_12000) { 06523 if (option_debug > 1) 06524 ast_log(LOG_DEBUG, "T38MaxBitRate 12000 found\n"); 06525 return 12000; 06526 } else if (maxrate & T38FAX_RATE_9600) { 06527 if (option_debug > 1) 06528 ast_log(LOG_DEBUG, "T38MaxBitRate 9600 found\n"); 06529 return 9600; 06530 } else if (maxrate & T38FAX_RATE_7200) { 06531 if (option_debug > 1) 06532 ast_log(LOG_DEBUG, "T38MaxBitRate 7200 found\n"); 06533 return 7200; 06534 } else if (maxrate & T38FAX_RATE_4800) { 06535 if (option_debug > 1) 06536 ast_log(LOG_DEBUG, "T38MaxBitRate 4800 found\n"); 06537 return 4800; 06538 } else if (maxrate & T38FAX_RATE_2400) { 06539 if (option_debug > 1) 06540 ast_log(LOG_DEBUG, "T38MaxBitRate 2400 found\n"); 06541 return 2400; 06542 } else { 06543 if (option_debug > 1) 06544 ast_log(LOG_DEBUG, "Strange, T38MaxBitRate NOT found in peers T38 SDP.\n"); 06545 return 0; 06546 } 06547 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 17473 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().
17474 { 17475 struct sip_peer *peer; 17476 17477 if (!(peer = ast_calloc(1, sizeof(*peer)))) 17478 return NULL; 17479 17480 apeerobjs++; 17481 ASTOBJ_INIT(peer); 17482 set_peer_defaults(peer); 17483 17484 ast_copy_string(peer->name, name, sizeof(peer->name)); 17485 17486 ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT); 17487 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 17488 peer->prefs = default_prefs; 17489 reg_source_db(peer); 17490 17491 return peer; 17492 }
static void temp_pvt_cleanup | ( | void * | ) | [static] |
Definition at line 6289 of file chan_sip.c.
References ast_string_field_free_memory, and free.
06290 { 06291 struct sip_pvt *p = data; 06292 06293 ast_string_field_free_memory(p); 06294 06295 free(data); 06296 }
static void temp_pvt_init | ( | void | ) | [static] |
static char * transfermode2str | ( | enum transfermodes | mode | ) | const [static] |
Convert transfer mode to text string.
Definition at line 10202 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().
10203 { 10204 if (mode == TRANSFER_OPENFORALL) 10205 return "open"; 10206 else if (mode == TRANSFER_CLOSED) 10207 return "closed"; 10208 return "strict"; 10209 }
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 8918 of file chan_sip.c.
References ast_dynamic_str_thread_get(), ast_dynamic_str_thread_set(), AST_DYNSTR_BUILD_FAILED, ast_random(), ast_skip_blanks(), ast_string_field_build, 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, 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().
08919 { 08920 /* We have to emulate EXACTLY what we'd get with a good peer 08921 * and a bad password, or else we leak information. */ 08922 const char *response = "407 Proxy Authentication Required"; 08923 const char *reqheader = "Proxy-Authorization"; 08924 const char *respheader = "Proxy-Authenticate"; 08925 const char *authtoken; 08926 struct ast_dynamic_str *buf; 08927 char *c; 08928 08929 /* table of recognised keywords, and their value in the digest */ 08930 enum keys { K_NONCE, K_LAST }; 08931 struct x { 08932 const char *key; 08933 const char *s; 08934 } *i, keys[] = { 08935 [K_NONCE] = { "nonce=", "" }, 08936 [K_LAST] = { NULL, NULL} 08937 }; 08938 08939 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 08940 response = "401 Unauthorized"; 08941 reqheader = "Authorization"; 08942 respheader = "WWW-Authenticate"; 08943 } 08944 authtoken = get_header(req, reqheader); 08945 if (ast_test_flag(req, SIP_PKT_IGNORE) && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 08946 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 08947 * information */ 08948 transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0); 08949 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 08950 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08951 return; 08952 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 08953 /* We have no auth, so issue challenge and request authentication */ 08954 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08955 transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0); 08956 /* Schedule auto destroy in 32 seconds */ 08957 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08958 return; 08959 } 08960 08961 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) { 08962 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08963 return; 08964 } 08965 08966 /* Make a copy of the response and parse it */ 08967 if (ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) { 08968 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08969 return; 08970 } 08971 08972 c = buf->str; 08973 08974 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 08975 for (i = keys; i->key != NULL; i++) { 08976 const char *separator = ","; /* default */ 08977 08978 if (strncasecmp(c, i->key, strlen(i->key)) != 0) { 08979 continue; 08980 } 08981 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08982 c += strlen(i->key); 08983 if (*c == '"') { /* in quotes. Skip first and look for last */ 08984 c++; 08985 separator = "\""; 08986 } 08987 i->s = c; 08988 strsep(&c, separator); 08989 break; 08990 } 08991 if (i->key == NULL) { /* not found, jump after space or comma */ 08992 strsep(&c, " ,"); 08993 } 08994 } 08995 08996 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 08997 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { 08998 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 08999 ast_string_field_build(p, randdata, "%08lx", ast_random()); 09000 } 09001 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 09002 09003 /* Schedule auto destroy in 32 seconds */ 09004 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09005 } else { 09006 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 09007 } 09008 }
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 8084 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
08085 { 08086 struct sip_request req; 08087 08088 reqprep(&req, p, SIP_INFO, 0, 1); 08089 add_digit(&req, digit, duration); 08090 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08091 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 8094 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
08095 { 08096 struct sip_request req; 08097 08098 reqprep(&req, p, SIP_INFO, 0, 1); 08099 add_vidupdate(&req); 08100 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08101 }
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 7324 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_sdp(), add_t38_sdp(), sip_invite_param::addsipheaders, ALLOWED_METHODS, append_date(), ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), ast_udptl_offered_from_local(), ast_var_name(), ast_var_value(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::branch, build_via(), ast_var_t::entries, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::invite_branch, sip_pvt::lastinvite, LOG_DEBUG, sip_request::method, ast_channel::name, sip_pvt::ocseq, option_debug, sip_pvt::options, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_to, sip_refer::referred_by, sip_refer::referred_by_name, sip_invite_param::replaces, reqprep(), sip_pvt::rtp, send_request(), SIP_REFER, SIPBUFSIZE, sipdebug, t38properties::state, SUPPORTED_EXTENSIONS, sip_pvt::t38, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, sip_pvt::udptl, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.
Referenced by do_proxy_auth(), sip_call(), and sip_poke_peer().
07325 { 07326 struct sip_request req; 07327 07328 req.method = sipmethod; 07329 if (init) { /* Seems like init always is 2 */ 07330 /* Bump branch even on initial requests */ 07331 p->branch ^= ast_random(); 07332 p->invite_branch = p->branch; 07333 build_via(p); 07334 if (init > 1) 07335 initreqprep(&req, p, sipmethod); 07336 else 07337 reqprep(&req, p, sipmethod, 0, 0); 07338 } else 07339 reqprep(&req, p, sipmethod, 0, 1); 07340 07341 if (p->options && p->options->auth) 07342 add_header(&req, p->options->authheader, p->options->auth); 07343 append_date(&req); 07344 if (sipmethod == SIP_REFER) { /* Call transfer */ 07345 if (p->refer) { 07346 char buf[SIPBUFSIZE]; 07347 if (!ast_strlen_zero(p->refer->refer_to)) 07348 add_header(&req, "Refer-To", p->refer->refer_to); 07349 if (!ast_strlen_zero(p->refer->referred_by)) { 07350 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 07351 add_header(&req, "Referred-By", buf); 07352 } 07353 } 07354 } 07355 /* This new INVITE is part of an attended transfer. Make sure that the 07356 other end knows and replace the current call with this new call */ 07357 if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) { 07358 add_header(&req, "Replaces", p->options->replaces); 07359 add_header(&req, "Require", "replaces"); 07360 } 07361 07362 add_header(&req, "Allow", ALLOWED_METHODS); 07363 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07364 if (p->options && p->options->addsipheaders && p->owner) { 07365 struct ast_channel *chan = p->owner; /* The owner channel */ 07366 struct varshead *headp; 07367 07368 ast_channel_lock(chan); 07369 07370 headp = &chan->varshead; 07371 07372 if (!headp) 07373 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 07374 else { 07375 const struct ast_var_t *current; 07376 AST_LIST_TRAVERSE(headp, current, entries) { 07377 /* SIPADDHEADER: Add SIP header to outgoing call */ 07378 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 07379 char *content, *end; 07380 const char *header = ast_var_value(current); 07381 char *headdup = ast_strdupa(header); 07382 07383 /* Strip of the starting " (if it's there) */ 07384 if (*headdup == '"') 07385 headdup++; 07386 if ((content = strchr(headdup, ':'))) { 07387 *content++ = '\0'; 07388 content = ast_skip_blanks(content); /* Skip white space */ 07389 /* Strip the ending " (if it's there) */ 07390 end = content + strlen(content) -1; 07391 if (*end == '"') 07392 *end = '\0'; 07393 07394 add_header(&req, headdup, content); 07395 if (sipdebug) 07396 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 07397 } 07398 } 07399 } 07400 } 07401 07402 ast_channel_unlock(chan); 07403 } 07404 if (sdp) { 07405 if (p->udptl && (p->t38.state == T38_LOCAL_DIRECT || p->t38.state == T38_LOCAL_REINVITE)) { 07406 ast_udptl_offered_from_local(p->udptl, 1); 07407 if (option_debug) 07408 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 07409 add_t38_sdp(&req, p); 07410 } else if (p->rtp) 07411 add_sdp(&req, p); 07412 } else { 07413 add_header_contentLength(&req, 0); 07414 } 07415 07416 if (!p->initreq.headers || init > 2) 07417 initialize_initreq(p, &req); 07418 p->lastinvite = p->ocseq; 07419 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 07420 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 7993 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().
07994 { 07995 struct sip_request req; 07996 07997 reqprep(&req, p, SIP_MESSAGE, 0, 1); 07998 add_text(&req, text); 07999 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08000 }
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 7611 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_test_flag, sip_pvt::expiry, sip_pvt::flags, sip_pvt::fromdomain, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::ocseq, sip_pvt::ourip, S_OR, send_request(), SIP_NOTIFY, SIP_PAGE2_BUGGY_MWI, sip_pvt::subscribed, t, and XMIT_RELIABLE.
Referenced by sip_send_mwi_to_peer().
07612 { 07613 struct sip_request req; 07614 char tmp[500]; 07615 char *t = tmp; 07616 size_t maxbytes = sizeof(tmp); 07617 07618 initreqprep(&req, p, SIP_NOTIFY); 07619 add_header(&req, "Event", "message-summary"); 07620 add_header(&req, "Content-Type", default_notifymime); 07621 07622 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 07623 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 07624 S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 07625 /* Cisco has a bug in the SIP stack where it can't accept the 07626 (0/0) notification. This can temporarily be disabled in 07627 sip.conf with the "buggymwi" option */ 07628 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)")); 07629 07630 if (p->subscribed) { 07631 if (p->expiry) 07632 add_header(&req, "Subscription-State", "active"); 07633 else /* Expired */ 07634 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07635 } 07636 07637 if (t > tmp + sizeof(tmp)) 07638 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07639 07640 add_header_contentLength(&req, strlen(tmp)); 07641 add_line(&req, tmp); 07642 07643 if (!p->initreq.headers) 07644 initialize_initreq(p, &req); 07645 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07646 }
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 7657 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ALLOWED_METHODS, sip_request::headers, initialize_initreq(), sip_pvt::initreq, sip_pvt::lastnoninvite, sip_pvt::ocseq, reqprep(), send_request(), SIP_NOTIFY, SIPBUFSIZE, SUPPORTED_EXTENSIONS, and XMIT_RELIABLE.
Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().
07658 { 07659 struct sip_request req; 07660 char tmp[SIPBUFSIZE/2]; 07661 07662 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07663 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 07664 add_header(&req, "Event", tmp); 07665 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 07666 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 07667 add_header(&req, "Allow", ALLOWED_METHODS); 07668 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07669 07670 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 07671 add_header_contentLength(&req, strlen(tmp)); 07672 add_line(&req, tmp); 07673 07674 if (!p->initreq.headers) 07675 initialize_initreq(p, &req); 07676 07677 p->lastnoninvite = p->ocseq; 07678 07679 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07680 }
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 8014 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().
08015 { 08016 struct sip_request req = { 08017 .headers = 0, 08018 }; 08019 char from[256]; 08020 const char *of; 08021 char *c; 08022 char referto[256]; 08023 char *ttag, *ftag; 08024 char *theirtag = ast_strdupa(p->theirtag); 08025 08026 if (option_debug || sipdebug) 08027 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 08028 08029 /* Are we transfering an inbound or outbound call ? */ 08030 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 08031 of = get_header(&p->initreq, "To"); 08032 ttag = theirtag; 08033 ftag = p->tag; 08034 } else { 08035 of = get_header(&p->initreq, "From"); 08036 ftag = theirtag; 08037 ttag = p->tag; 08038 } 08039 08040 ast_copy_string(from, of, sizeof(from)); 08041 of = get_in_brackets(from); 08042 ast_string_field_set(p, from, of); 08043 if (strncasecmp(of, "sip:", 4)) 08044 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 08045 else 08046 of += 4; 08047 /* Get just the username part */ 08048 if ((c = strchr(dest, '@'))) 08049 c = NULL; 08050 else if ((c = strchr(of, '@'))) 08051 *c++ = '\0'; 08052 if (c) 08053 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 08054 else 08055 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 08056 08057 /* save in case we get 407 challenge */ 08058 sip_refer_allocate(p); 08059 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 08060 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 08061 p->refer->status = REFER_SENT; /* Set refer status */ 08062 08063 reqprep(&req, p, SIP_REFER, 0, 1); 08064 08065 add_header(&req, "Refer-To", referto); 08066 add_header(&req, "Allow", ALLOWED_METHODS); 08067 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 08068 if (!ast_strlen_zero(p->our_contact)) 08069 add_header(&req, "Referred-By", p->our_contact); 08070 08071 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 08072 /* We should propably wait for a NOTIFY here until we ack the transfer */ 08073 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 08074 08075 /*! \todo In theory, we should hang around and wait for a reply, before 08076 returning to the dial plan here. Don't know really how that would 08077 affect the transfer() app or the pbx, but, well, to make this 08078 useful we should have a STATUS code on transfer(). 08079 */ 08080 }
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 7785 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().
07786 { 07787 struct sip_request req; 07788 char from[256]; 07789 char to[256]; 07790 char tmp[80]; 07791 char addr[80]; 07792 struct sip_pvt *p; 07793 char *fromdomain; 07794 07795 /* exit if we are already in process with this registrar ?*/ 07796 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 07797 if (r) { 07798 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 07799 } 07800 return 0; 07801 } 07802 07803 if (r->call) { /* We have a registration */ 07804 if (!auth) { 07805 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 07806 return 0; 07807 } else { 07808 p = r->call; 07809 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 07810 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 07811 } 07812 } else { 07813 /* Build callid for registration if we haven't registered before */ 07814 if (!r->callid_valid) { 07815 build_callid_registry(r, __ourip, default_fromdomain); 07816 r->callid_valid = TRUE; 07817 } 07818 /* Allocate SIP packet for registration */ 07819 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) { 07820 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 07821 return 0; 07822 } 07823 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07824 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 07825 /* Find address to hostname if we haven't tried to connect 07826 * or a connection error has occurred */ 07827 if (create_addr(p, r->hostname, r->needdns ? NULL : &r->us)) { 07828 /* we have what we hope is a temporary network error, 07829 * probably DNS. We need to reschedule a registration try */ 07830 sip_destroy(p); 07831 07832 if (r->timeout > -1) 07833 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 07834 else 07835 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); 07836 07837 AST_SCHED_DEL(sched, r->timeout); 07838 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07839 r->regattempts++; 07840 return 0; 07841 } 07842 if (r->needdns) { 07843 memcpy(&r->us, &p->sa, sizeof(r->us)); 07844 } 07845 r->needdns = FALSE; 07846 /* Copy back Call-ID in case create_addr changed it */ 07847 ast_string_field_set(r, callid, p->callid); 07848 if (r->portno) { 07849 p->sa.sin_port = htons(r->portno); 07850 p->recv.sin_port = htons(r->portno); 07851 } else /* Set registry port to the port set from the peer definition/srv or default */ 07852 r->portno = ntohs(p->sa.sin_port); 07853 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 07854 r->call=p; /* Save pointer to SIP packet */ 07855 p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ 07856 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 07857 ast_string_field_set(p, peersecret, r->secret); 07858 if (!ast_strlen_zero(r->md5secret)) 07859 ast_string_field_set(p, peermd5secret, r->md5secret); 07860 /* User name in this realm 07861 - if authuser is set, use that, otherwise use username */ 07862 if (!ast_strlen_zero(r->authuser)) { 07863 ast_string_field_set(p, peername, r->authuser); 07864 ast_string_field_set(p, authname, r->authuser); 07865 } else if (!ast_strlen_zero(r->username)) { 07866 ast_string_field_set(p, peername, r->username); 07867 ast_string_field_set(p, authname, r->username); 07868 ast_string_field_set(p, fromuser, r->username); 07869 } 07870 if (!ast_strlen_zero(r->username)) 07871 ast_string_field_set(p, username, r->username); 07872 /* Save extension in packet */ 07873 ast_string_field_set(p, exten, r->contact); 07874 07875 /* 07876 check which address we should use in our contact header 07877 based on whether the remote host is on the external or 07878 internal network so we can register through nat 07879 */ 07880 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 07881 p->ourip = bindaddr.sin_addr; 07882 build_contact(p); 07883 } 07884 07885 /* set up a timeout */ 07886 if (auth == NULL) { 07887 if (r->timeout > -1) 07888 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 07889 AST_SCHED_DEL(sched, r->timeout); 07890 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07891 if (option_debug) 07892 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 07893 } 07894 07895 if ((fromdomain = strchr(r->username, '@'))) { 07896 /* the domain name is just behind '@' */ 07897 fromdomain++ ; 07898 /* We have a domain in the username for registration */ 07899 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 07900 if (!ast_strlen_zero(p->theirtag)) 07901 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 07902 else 07903 snprintf(to, sizeof(to), "<sip:%s>", r->username); 07904 07905 /* If the registration username contains '@', then the domain should be used as 07906 the equivalent of "fromdomain" for the registration */ 07907 if (ast_strlen_zero(p->fromdomain)) { 07908 ast_string_field_set(p, fromdomain, fromdomain); 07909 } 07910 } else { 07911 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 07912 if (!ast_strlen_zero(p->theirtag)) 07913 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 07914 else 07915 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 07916 } 07917 07918 /* Fromdomain is what we are registering to, regardless of actual 07919 host name from SRV */ 07920 if (!ast_strlen_zero(p->fromdomain)) { 07921 if (r->portno && r->portno != STANDARD_SIP_PORT) 07922 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 07923 else 07924 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 07925 } else { 07926 if (r->portno && r->portno != STANDARD_SIP_PORT) 07927 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 07928 else 07929 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 07930 } 07931 ast_string_field_set(p, uri, addr); 07932 07933 p->branch ^= ast_random(); 07934 07935 init_req(&req, sipmethod, addr); 07936 07937 /* Add to CSEQ */ 07938 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 07939 p->ocseq = r->ocseq; 07940 07941 build_via(p); 07942 add_header(&req, "Via", p->via); 07943 add_header(&req, "From", from); 07944 add_header(&req, "To", to); 07945 add_header(&req, "Call-ID", p->callid); 07946 add_header(&req, "CSeq", tmp); 07947 if (!ast_strlen_zero(global_useragent)) 07948 add_header(&req, "User-Agent", global_useragent); 07949 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07950 07951 07952 if (auth) /* Add auth header */ 07953 add_header(&req, authheader, auth); 07954 else if (!ast_strlen_zero(r->nonce)) { 07955 char digest[1024]; 07956 07957 /* We have auth data to reuse, build a digest header! */ 07958 if (sipdebug) 07959 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 07960 ast_string_field_set(p, realm, r->realm); 07961 ast_string_field_set(p, nonce, r->nonce); 07962 ast_string_field_set(p, domain, r->domain); 07963 ast_string_field_set(p, opaque, r->opaque); 07964 ast_string_field_set(p, qop, r->qop); 07965 r->noncecount++; 07966 p->noncecount = r->noncecount; 07967 07968 memset(digest,0,sizeof(digest)); 07969 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 07970 add_header(&req, "Authorization", digest); 07971 else 07972 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 07973 07974 } 07975 07976 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 07977 add_header(&req, "Expires", tmp); 07978 add_header(&req, "Contact", p->our_contact); 07979 add_header(&req, "Event", "registration"); 07980 add_header_contentLength(&req, 0); 07981 07982 initialize_initreq(p, &req); 07983 if (sip_debug_test_pvt(p)) 07984 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 07985 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 07986 r->regattempts++; /* Another attempt */ 07987 if (option_debug > 3) 07988 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 07989 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07990 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with SDP.
Definition at line 7044 of file chan_sip.c.
References add_header(), add_sdp(), ALLOWED_METHODS, append_history, ast_set_flag, ast_test_flag, sip_pvt::flags, initialize_initreq(), reqprep(), send_request(), SIP_INVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, sipdebug, SUPPORTED_EXTENSIONS, and XMIT_CRITICAL.
Referenced by check_pendings(), and sip_set_rtp_peer().
07045 { 07046 struct sip_request req; 07047 07048 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 07049 07050 add_header(&req, "Allow", ALLOWED_METHODS); 07051 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07052 if (sipdebug) 07053 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 07054 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07055 append_history(p, "ReInv", "Re-invite sent"); 07056 add_sdp(&req, p); 07057 /* Use this as the basis */ 07058 initialize_initreq(p, &req); 07059 p->lastinvite = p->ocseq; 07060 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 07061 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07062 }
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 7068 of file chan_sip.c.
References add_header(), add_t38_sdp(), ALLOWED_METHODS, ast_set_flag, ast_test_flag, ast_udptl_offered_from_local(), sip_pvt::flags, initialize_initreq(), sip_pvt::lastinvite, sip_pvt::ocseq, reqprep(), send_request(), SIP_INVITE, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, sipdebug, SUPPORTED_EXTENSIONS, sip_pvt::udptl, and XMIT_CRITICAL.
Referenced by sip_handle_t38_reinvite(), sip_read(), and sip_set_udptl_peer().
07069 { 07070 struct sip_request req; 07071 07072 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 07073 07074 add_header(&req, "Allow", ALLOWED_METHODS); 07075 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07076 if (sipdebug) 07077 add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)"); 07078 ast_udptl_offered_from_local(p->udptl, 1); 07079 add_t38_sdp(&req, p); 07080 /* Use this as the basis */ 07081 initialize_initreq(p, &req); 07082 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 07083 p->lastinvite = p->ocseq; 07084 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07085 }
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 8106 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().
08107 { 08108 struct sip_request resp; 08109 08110 if (sipmethod == SIP_ACK) 08111 p->invitestate = INV_CONFIRMED; 08112 08113 reqprep(&resp, p, sipmethod, seqno, newbranch); 08114 add_header_contentLength(&resp, 0); 08115 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 08116 }
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 8119 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().
08120 { 08121 struct sip_request resp; 08122 08123 reqprep(&resp, p, sipmethod, seqno, newbranch); 08124 if (!ast_strlen_zero(p->realm)) { 08125 char digest[1024]; 08126 08127 memset(digest, 0, sizeof(digest)); 08128 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 08129 if (p->options && p->options->auth_type == PROXY_AUTH) 08130 add_header(&resp, "Proxy-Authorization", digest); 08131 else if (p->options && p->options->auth_type == WWW_AUTH) 08132 add_header(&resp, "Authorization", digest); 08133 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 08134 add_header(&resp, "Proxy-Authorization", digest); 08135 } else 08136 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 08137 } 08138 /* If we are hanging up and know a cause for that, send it in clear text to make 08139 debugging easier. */ 08140 if (sipmethod == SIP_BYE) { 08141 char buf[10]; 08142 08143 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->hangupcause)); 08144 snprintf(buf, sizeof(buf), "%d", p->hangupcause); 08145 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 08146 } 08147 08148 add_header_contentLength(&resp, 0); 08149 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 08150 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 6350 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
06351 { 06352 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06353 }
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 6369 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().
06370 { 06371 return __transmit_response(p, msg, req, XMIT_CRITICAL); 06372 }
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 6299 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.
06300 { 06301 struct sip_pvt *p = NULL; 06302 06303 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 06304 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 06305 return -1; 06306 } 06307 06308 /* if the structure was just allocated, initialize it */ 06309 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 06310 ast_set_flag(&p->flags[0], SIP_NO_HISTORY); 06311 if (ast_string_field_init(p, 512)) 06312 return -1; 06313 } 06314 06315 /* Initialize the bare minimum */ 06316 p->method = intended_method; 06317 06318 if (sin) { 06319 p->sa = *sin; 06320 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 06321 p->ourip = __ourip; 06322 } else 06323 p->ourip = __ourip; 06324 06325 p->branch = ast_random(); 06326 make_our_tag(p->tag, sizeof(p->tag)); 06327 p->ocseq = INITIAL_CSEQ; 06328 06329 if (useglobal_nat && sin) { 06330 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 06331 p->recv = *sin; 06332 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 06333 } 06334 check_via(p, req); 06335 06336 ast_string_field_set(p, fromdomain, default_fromdomain); 06337 build_via(p); 06338 ast_string_field_set(p, callid, callid); 06339 06340 /* Use this temporary pvt structure to send the message */ 06341 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06342 06343 /* Free the string fields, but not the pool space */ 06344 ast_string_field_reset_all(p); 06345 06346 return 0; 06347 }
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 6397 of file chan_sip.c.
References add_header(), add_header_contentLength(), respprep(), and send_response().
Referenced by handle_request(), and handle_request_options().
06398 { 06399 struct sip_request resp; 06400 respprep(&resp, p, msg, req); 06401 add_header(&resp, "Accept", "application/sdp"); 06402 add_header_contentLength(&resp, 0); 06403 return send_response(p, &resp, reliable, 0); 06404 }
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 6407 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().
06408 { 06409 struct sip_request resp; 06410 char tmp[512]; 06411 int seqno = 0; 06412 06413 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06414 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06415 return -1; 06416 } 06417 /* Stale means that they sent us correct authentication, but 06418 based it on an old challenge (nonce) */ 06419 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 06420 respprep(&resp, p, msg, req); 06421 add_header(&resp, header, tmp); 06422 add_header_contentLength(&resp, 0); 06423 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 06424 return send_response(p, &resp, reliable, seqno); 06425 }
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 6387 of file chan_sip.c.
References add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
06388 { 06389 struct sip_request resp; 06390 respprep(&resp, p, msg, req); 06391 append_date(&resp); 06392 add_header_contentLength(&resp, 0); 06393 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06394 }
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 6973 of file chan_sip.c.
References add_sdp(), ast_log(), ast_rtp_codec_setpref(), ast_test_flag, sip_pvt::autoframing, sip_pvt::callid, sip_pvt::flags, get_header(), LOG_DEBUG, LOG_ERROR, option_debug, sip_pvt::pendinginvite, sip_pvt::prefs, respprep(), sip_pvt::rtp, send_response(), SIP_OUTGOING, and try_suggested_sip_codec().
Referenced by handle_invite_replaces(), handle_request_invite(), sip_answer(), sip_indicate(), and sip_write().
06974 { 06975 struct sip_request resp; 06976 int seqno; 06977 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06978 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06979 return -1; 06980 } 06981 respprep(&resp, p, msg, req); 06982 if (p->rtp) { 06983 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06984 if (option_debug) 06985 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 06986 ast_rtp_codec_setpref(p->rtp, &p->prefs); 06987 } 06988 try_suggested_sip_codec(p); 06989 add_sdp(&resp, p); 06990 } else 06991 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 06992 if (reliable && !p->pendinginvite) 06993 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06994 return send_response(p, &resp, reliable, seqno); 06995 }
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 6933 of file chan_sip.c.
References add_t38_sdp(), ast_log(), ast_udptl_offered_from_local(), sip_pvt::callid, get_header(), LOG_ERROR, sip_pvt::pendinginvite, respprep(), send_response(), and sip_pvt::udptl.
Referenced by handle_request_invite(), sip_answer(), and sip_handle_t38_reinvite().
06934 { 06935 struct sip_request resp; 06936 int seqno; 06937 06938 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06939 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06940 return -1; 06941 } 06942 respprep(&resp, p, msg, req); 06943 if (p->udptl) { 06944 ast_udptl_offered_from_local(p->udptl, 0); 06945 add_t38_sdp(&resp, p); 06946 } else 06947 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 06948 if (retrans && !p->pendinginvite) 06949 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06950 return send_response(p, &resp, retrans, seqno); 06951 }
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 6356 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
06357 { 06358 struct sip_request resp; 06359 respprep(&resp, p, msg, req); 06360 append_date(&resp); 06361 add_header(&resp, "Unsupported", unsupported); 06362 add_header_contentLength(&resp, 0); 06363 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06364 }
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 7649 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().
07650 { 07651 if (!p->initreq.headers) /* Initialize first request before sending */ 07652 initialize_initreq(p, req); 07653 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 07654 }
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 7423 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().
07424 { 07425 char tmp[4000], from[256], to[256]; 07426 char *t = tmp, *c, *mfrom, *mto; 07427 size_t maxbytes = sizeof(tmp); 07428 struct sip_request req; 07429 char hint[AST_MAX_EXTENSION]; 07430 char *statestring = "terminated"; 07431 const struct cfsubscription_types *subscriptiontype; 07432 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 07433 char *pidfstate = "--"; 07434 char *pidfnote= "Ready"; 07435 07436 memset(from, 0, sizeof(from)); 07437 memset(to, 0, sizeof(to)); 07438 memset(tmp, 0, sizeof(tmp)); 07439 07440 switch (state) { 07441 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 07442 statestring = (global_notifyringing) ? "early" : "confirmed"; 07443 local_state = NOTIFY_INUSE; 07444 pidfstate = "busy"; 07445 pidfnote = "Ringing"; 07446 break; 07447 case AST_EXTENSION_RINGING: 07448 statestring = "early"; 07449 local_state = NOTIFY_INUSE; 07450 pidfstate = "busy"; 07451 pidfnote = "Ringing"; 07452 break; 07453 case AST_EXTENSION_INUSE: 07454 statestring = "confirmed"; 07455 local_state = NOTIFY_INUSE; 07456 pidfstate = "busy"; 07457 pidfnote = "On the phone"; 07458 break; 07459 case AST_EXTENSION_BUSY: 07460 statestring = "confirmed"; 07461 local_state = NOTIFY_CLOSED; 07462 pidfstate = "busy"; 07463 pidfnote = "On the phone"; 07464 break; 07465 case AST_EXTENSION_UNAVAILABLE: 07466 statestring = "terminated"; 07467 local_state = NOTIFY_CLOSED; 07468 pidfstate = "away"; 07469 pidfnote = "Unavailable"; 07470 break; 07471 case AST_EXTENSION_ONHOLD: 07472 statestring = "confirmed"; 07473 local_state = NOTIFY_CLOSED; 07474 pidfstate = "busy"; 07475 pidfnote = "On Hold"; 07476 break; 07477 case AST_EXTENSION_NOT_INUSE: 07478 default: 07479 /* Default setting */ 07480 break; 07481 } 07482 07483 subscriptiontype = find_subscription_type(p->subscribed); 07484 07485 /* Check which device/devices we are watching and if they are registered */ 07486 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 07487 char *hint2 = hint, *individual_hint = NULL; 07488 int hint_count = 0, unavailable_count = 0; 07489 07490 while ((individual_hint = strsep(&hint2, "&"))) { 07491 hint_count++; 07492 07493 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 07494 unavailable_count++; 07495 } 07496 07497 /* If none of the hinted devices are registered, we will 07498 * override notification and show no availability. 07499 */ 07500 if (hint_count > 0 && hint_count == unavailable_count) { 07501 local_state = NOTIFY_CLOSED; 07502 pidfstate = "away"; 07503 pidfnote = "Not online"; 07504 } 07505 } 07506 07507 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 07508 c = get_in_brackets(from); 07509 if (strncasecmp(c, "sip:", 4)) { 07510 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07511 return -1; 07512 } 07513 mfrom = strsep(&c, ";"); /* trim ; and beyond */ 07514 07515 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 07516 c = get_in_brackets(to); 07517 if (strncasecmp(c, "sip:", 4)) { 07518 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07519 return -1; 07520 } 07521 mto = strsep(&c, ";"); /* trim ; and beyond */ 07522 07523 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07524 07525 07526 add_header(&req, "Event", subscriptiontype->event); 07527 add_header(&req, "Content-Type", subscriptiontype->mediatype); 07528 switch(state) { 07529 case AST_EXTENSION_DEACTIVATED: 07530 if (timeout) 07531 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07532 else { 07533 add_header(&req, "Subscription-State", "terminated;reason=probation"); 07534 add_header(&req, "Retry-After", "60"); 07535 } 07536 break; 07537 case AST_EXTENSION_REMOVED: 07538 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 07539 break; 07540 default: 07541 if (p->expiry) 07542 add_header(&req, "Subscription-State", "active"); 07543 else /* Expired */ 07544 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07545 } 07546 switch (p->subscribed) { 07547 case XPIDF_XML: 07548 case CPIM_PIDF_XML: 07549 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07550 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 07551 ast_build_string(&t, &maxbytes, "<presence>\n"); 07552 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 07553 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 07554 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 07555 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 07556 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 07557 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 07558 break; 07559 case PIDF_XML: /* Eyebeam supports this format */ 07560 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 07561 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); 07562 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 07563 if (pidfstate[0] != '-') 07564 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 07565 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 07566 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 07567 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 07568 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 07569 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 07570 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 07571 else 07572 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 07573 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 07574 break; 07575 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 07576 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07577 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); 07578 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 07579 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 07580 else 07581 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 07582 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 07583 if (state == AST_EXTENSION_ONHOLD) { 07584 ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n" 07585 "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n" 07586 "</target>\n</local>\n", mto); 07587 } 07588 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 07589 break; 07590 case NONE: 07591 default: 07592 break; 07593 } 07594 07595 if (t > tmp + sizeof(tmp)) 07596 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07597 07598 add_header_contentLength(&req, strlen(tmp)); 07599 add_line(&req, tmp); 07600 p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */ 07601 07602 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07603 }
static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 3727 of file chan_sip.c.
References ast_getformatbyname(), ast_log(), sip_pvt::capability, sip_pvt::jointcapability, LOG_NOTICE, sip_pvt::owner, and pbx_builtin_getvar_helper().
Referenced by sip_answer(), and transmit_response_with_sdp().
03728 { 03729 int fmt; 03730 const char *codec; 03731 03732 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 03733 if (!codec) 03734 return; 03735 03736 fmt = ast_getformatbyname(codec); 03737 if (fmt) { 03738 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 03739 if (p->jointcapability & fmt) { 03740 p->jointcapability &= fmt; 03741 p->capability &= fmt; 03742 } else 03743 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 03744 } else 03745 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 03746 return; 03747 }
static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 19097 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.
19098 { 19099 struct sip_pvt *p, *pl; 19100 19101 /* First, take us out of the channel type list */ 19102 ast_channel_unregister(&sip_tech); 19103 19104 /* Unregister dial plan functions */ 19105 ast_custom_function_unregister(&sipchaninfo_function); 19106 ast_custom_function_unregister(&sippeer_function); 19107 ast_custom_function_unregister(&sip_header_function); 19108 ast_custom_function_unregister(&checksipdomain_function); 19109 19110 /* Unregister dial plan applications */ 19111 ast_unregister_application(app_dtmfmode); 19112 ast_unregister_application(app_sipaddheader); 19113 19114 /* Unregister CLI commands */ 19115 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 19116 19117 /* Disconnect from the RTP subsystem */ 19118 ast_rtp_proto_unregister(&sip_rtp); 19119 19120 /* Disconnect from UDPTL */ 19121 ast_udptl_proto_unregister(&sip_udptl); 19122 19123 /* Unregister AMI actions */ 19124 ast_manager_unregister("SIPpeers"); 19125 ast_manager_unregister("SIPshowpeer"); 19126 19127 ast_mutex_lock(&iflock); 19128 /* Hangup all interfaces if they have an owner */ 19129 for (p = iflist; p ; p = p->next) { 19130 if (p->owner) 19131 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 19132 } 19133 ast_mutex_unlock(&iflock); 19134 19135 ast_mutex_lock(&monlock); 19136 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 19137 pthread_cancel(monitor_thread); 19138 pthread_kill(monitor_thread, SIGURG); 19139 pthread_join(monitor_thread, NULL); 19140 } 19141 monitor_thread = AST_PTHREADT_STOP; 19142 ast_mutex_unlock(&monlock); 19143 19144 restartdestroy: 19145 ast_mutex_lock(&iflock); 19146 /* Destroy all the interfaces and free their memory */ 19147 p = iflist; 19148 while (p) { 19149 pl = p; 19150 p = p->next; 19151 if (__sip_destroy(pl, TRUE) < 0) { 19152 /* Something is still bridged, let it react to getting a hangup */ 19153 iflist = p; 19154 ast_mutex_unlock(&iflock); 19155 usleep(1); 19156 goto restartdestroy; 19157 } 19158 } 19159 iflist = NULL; 19160 ast_mutex_unlock(&iflock); 19161 19162 /* Free memory for local network address mask */ 19163 ast_free_ha(localaddr); 19164 19165 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 19166 ASTOBJ_CONTAINER_DESTROY(&userl); 19167 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 19168 ASTOBJ_CONTAINER_DESTROY(&peerl); 19169 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 19170 ASTOBJ_CONTAINER_DESTROY(®l); 19171 19172 clear_realm_authentication(authl); 19173 clear_sip_domains(); 19174 close(sipsock); 19175 sched_context_destroy(sched); 19176 19177 return 0; 19178 }
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 3274 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().
03275 { 03276 char name[256]; 03277 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 03278 int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL); 03279 struct sip_user *u = NULL; 03280 struct sip_peer *p = NULL; 03281 03282 if (option_debug > 2) 03283 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 03284 03285 /* Test if we need to check call limits, in order to avoid 03286 realtime lookups if we do not need it */ 03287 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 03288 return 0; 03289 03290 ast_copy_string(name, fup->username, sizeof(name)); 03291 03292 /* Check the list of users only for incoming calls */ 03293 if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) { 03294 inuse = &u->inUse; 03295 call_limit = &u->call_limit; 03296 inringing = NULL; 03297 } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1, 0) ) ) { /* Try to find peer */ 03298 inuse = &p->inUse; 03299 call_limit = &p->call_limit; 03300 inringing = &p->inRinging; 03301 ast_copy_string(name, fup->peername, sizeof(name)); 03302 } 03303 if (!p && !u) { 03304 if (option_debug > 1) 03305 ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name); 03306 return 0; 03307 } 03308 03309 switch(event) { 03310 /* incoming and outgoing affects the inUse counter */ 03311 case DEC_CALL_LIMIT: 03312 if ( *inuse > 0 ) { 03313 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 03314 (*inuse)--; 03315 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 03316 } 03317 } else { 03318 *inuse = 0; 03319 } 03320 if (inringing) { 03321 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03322 if (*inringing > 0) 03323 (*inringing)--; 03324 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03325 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername); 03326 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03327 } 03328 } 03329 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) { 03330 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 03331 sip_peer_hold(fup, 0); 03332 } 03333 if (option_debug > 1 || sipdebug) { 03334 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 03335 } 03336 break; 03337 03338 case INC_CALL_RINGING: 03339 case INC_CALL_LIMIT: 03340 if (*call_limit > 0 ) { 03341 /* Let call limit affect only outgoing calls */ 03342 if (outgoing && (*inuse >= *call_limit)) { 03343 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); 03344 if (u) 03345 ASTOBJ_UNREF(u, sip_destroy_user); 03346 else 03347 ASTOBJ_UNREF(p, sip_destroy_peer); 03348 return -1; 03349 } 03350 } 03351 if (inringing && (event == INC_CALL_RINGING)) { 03352 if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03353 (*inringing)++; 03354 ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03355 } 03356 } 03357 /* Continue */ 03358 (*inuse)++; 03359 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 03360 if (option_debug > 1 || sipdebug) { 03361 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 03362 } 03363 break; 03364 03365 case DEC_CALL_RINGING: 03366 if (inringing) { 03367 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03368 if (*inringing > 0) 03369 (*inringing)--; 03370 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03371 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name); 03372 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03373 } 03374 } 03375 break; 03376 03377 default: 03378 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 03379 } 03380 if (p) { 03381 ast_device_state_changed("SIP/%s", p->name); 03382 ASTOBJ_UNREF(p, sip_destroy_peer); 03383 } else /* u must be set */ 03384 ASTOBJ_UNREF(u, sip_destroy_user); 03385 return 0; 03386 }
static void update_peer | ( | struct sip_peer * | p, | |
int | expiry | |||
) | [static] |
Update peer data in database (if used).
Definition at line 2531 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().
02532 { 02533 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02534 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) && 02535 (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) { 02536 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry, p->lastms); 02537 } 02538 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Session Initiation Protocol (SIP)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 19184 of file chan_sip.c.
struct in_addr __ourip [static] |
Definition at line 1228 of file chan_sip.c.
int allow_external_domains [static] |
Accept calls to external SIP domains?
Definition at line 566 of file chan_sip.c.
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 586 of file chan_sip.c.
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 18661 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 18663 of file chan_sip.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 19184 of file chan_sip.c.
Definition at line 1217 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 546 of file chan_sip.c.
struct sockaddr_in bindaddr = { 0, } [static] |
The address we bind to
Definition at line 1222 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 8672 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 18923 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 18928 of file chan_sip.c.
int compactheaders [static] |
send compact sip headers
Definition at line 560 of file chan_sip.c.
const char config[] = "sip.conf" [static] |
Definition at line 232 of file chan_sip.c.
char debug_usage[] [static] |
Definition at line 12123 of file chan_sip.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1231 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 526 of file chan_sip.c.
char default_context[AST_MAX_CONTEXT] [static] |
Definition at line 523 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 527 of file chan_sip.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled.
Definition at line 223 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Definition at line 525 of file chan_sip.c.
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 534 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 531 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 532 of file chan_sip.c.
char default_notifymime[AST_MAX_EXTENSION] [static] |
Definition at line 528 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 535 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 529 of file chan_sip.c.
char default_subscribecontext[AST_MAX_CONTEXT] [static] |
Definition at line 524 of file chan_sip.c.
char default_vmexten[AST_MAX_EXTENSION] [static] |
Definition at line 530 of file chan_sip.c.
char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static] |
Definition at line 18660 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 18666 of file chan_sip.c.
int dumphistory [static] |
Dump history to verbose before destroying SIP dialog
Definition at line 562 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 1225 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 1224 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 1223 of file chan_sip.c.
int externrefresh = 10 [static] |
int global_allowguest [static] |
allow unauthenticated users/peers to connect?
Definition at line 553 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 554 of file chan_sip.c.
enum transfermodes global_allowtransfer [static] |
SIP Refer restriction scheme
Definition at line 570 of file chan_sip.c.
int global_alwaysauthreject [static] |
Send 401 Unauthorized for all failing requests
Definition at line 543 of file chan_sip.c.
int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 569 of file chan_sip.c.
int global_callevents [static] |
Whether we send manager events or not
Definition at line 567 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 578 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 538 of file chan_sip.c.
int global_dynamic_exclude_static = 0 [static] |
Definition at line 579 of file chan_sip.c.
struct ast_flags global_flags[2] = {{0}} [static] |
global SIP_ flags
Definition at line 589 of file chan_sip.c.
Referenced by build_peer(), build_radius_record(), build_user(), destroy_association(), get_destination(), load_module(), realtime_update_peer(), set_peer_defaults(), sip_alloc(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), sip_no_debug_deprecated(), sip_show_settings(), transmit_response_using_temp(), and update_peer().
struct ast_jb_conf global_jbconf [static] |
Definition at line 230 of file chan_sip.c.
int global_limitonpeers [static] |
Match call limit on peers only
Definition at line 539 of file chan_sip.c.
int global_matchexterniplocally [static] |
Match externip/externhost setting against localnet setting
Definition at line 572 of file chan_sip.c.
int global_mwitime [static] |
Time between MWI checks for peers
Definition at line 556 of file chan_sip.c.
int global_notifyhold [static] |
Send notifications on hold
Definition at line 542 of file chan_sip.c.
int global_notifyringing [static] |
Send notifications on ringing
Definition at line 541 of file chan_sip.c.
char global_realm[MAXHOSTNAMELEN] [static] |
Default realm
Definition at line 563 of file chan_sip.c.
int global_reg_timeout [static] |
Definition at line 551 of file chan_sip.c.
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 552 of file chan_sip.c.
char global_regcontext[AST_MAX_CONTEXT] [static] |
Context for auto-extensions
Definition at line 564 of file chan_sip.c.
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 547 of file chan_sip.c.
int global_rtautoclear [static] |
Definition at line 540 of file chan_sip.c.
int global_rtpholdtimeout [static] |
Definition at line 549 of file chan_sip.c.
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 550 of file chan_sip.c.
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 548 of file chan_sip.c.
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 568 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 841 of file chan_sip.c.
unsigned int global_tos_audio [static] |
IP type of service for audio RTP packets
Definition at line 558 of file chan_sip.c.
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 557 of file chan_sip.c.
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 559 of file chan_sip.c.
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 565 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 12140 of file chan_sip.c.
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe
ast_mutex_t iflock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
struct io_context* io [static] |
The IO context
Definition at line 610 of file chan_sip.c.
List of local networks, on the same side of NAT as this Asterisk
Definition at line 1227 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 10751 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 10302 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 604 of file chan_sip.c.
ast_mutex_t monlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Definition at line 598 of file chan_sip.c.
ast_mutex_t netlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
Definition at line 596 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 12132 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 12136 of file chan_sip.c.
const char notify_config[] = "sip_notify.conf" [static] |
Definition at line 233 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 1233 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 12072 of file chan_sip.c.
int ourport [static] |
Definition at line 1230 of file chan_sip.c.
struct sockaddr_in outboundproxyip [static] |
Definition at line 1229 of file chan_sip.c.
int pedanticsipchecking [static] |
Extra checking ? Default off
Definition at line 545 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 12114 of file chan_sip.c.
int recordhistory [static] |
Record SIP history. Off by default
Definition at line 561 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 587 of file chan_sip.c.
int rpeerobjs = 0 [static] |
Realtime peers
Definition at line 585 of file chan_sip.c.
int ruserobjs = 0 [static] |
Realtime users
Definition at line 583 of file chan_sip.c.
struct sched_context* sched [static] |
The scheduling context
Definition at line 609 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 12096 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 12092 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 12067 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 12100 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 12087 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 12153 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 12109 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 12104 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 12119 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 12157 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 12149 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 12082 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 12077 of file chan_sip.c.
struct ast_custom_function sip_header_function [static] |
struct cfsip_methods sip_methods[] [static] |
XXX Note that sip_methods[i].id == i must hold or the code breaks
Referenced by __sip_ack(), __sip_autodestruct(), __sip_destroy(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), check_auth(), do_proxy_auth(), find_sip_method(), get_destination(), handle_request(), handle_request_subscribe(), handle_response(), init_req(), initreqprep(), method_match(), reqprep(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_scheddestroy(), and transmit_register().
struct cfsip_options sip_options[] [static] |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly.
Referenced by _sip_show_peer(), parse_sip_options(), and sip_show_channel().
ast_mutex_t sip_reload_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
char sip_reload_usage[] [static] |
Initial value:
"Usage: sip reload\n" " Reloads SIP configuration from sip.conf\n"
Definition at line 12145 of file chan_sip.c.
int sip_reloading = FALSE [static] |
Flag for avoiding multiple reloads at the same time
Definition at line 606 of file chan_sip.c.
enum channelreloadreason sip_reloadreason [static] |
Reason for last reload/load of configuration
Definition at line 607 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 1630 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 1572 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 1598 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 1639 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 12398 of file chan_sip.c.
Referenced by load_module(), and unload_module().
Structure to declare a dialplan function: SIPPEER.
Definition at line 12318 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 1221 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 611 of file chan_sip.c.
int speerobjs = 0 [static] |
Statis peers
Definition at line 584 of file chan_sip.c.
int srvlookup [static] |
SRV Lookup on or off. Default is on
Definition at line 544 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 582 of file chan_sip.c.
char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static] |
Definition at line 18659 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 18664 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.