#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) |
create address structure from peer name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success | |
static int | create_addr_from_peer (struct sip_pvt *dialog, struct sip_peer *peer) |
Create address structure from peer reference. return -1 on error, 0 on success. | |
static void | destroy_association (struct sip_peer *peer) |
Remove registration data from realtime database or AST/DB when registration expires. | |
static int | determine_firstline_parts (struct sip_request *req) |
Parse first line of incoming SIP request. | |
static void * | do_monitor (void *data) |
The SIP monitoring thread. | |
static int | do_proxy_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader, int sipmethod, int init) |
Add authentication on outbound SIP packet. | |
static int | do_register_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader) |
Authenticate for outbound registration. | |
static void | do_setnat (struct sip_pvt *p, int natflags) |
Set nat mode on the various data sockets. | |
static int | does_peer_need_mwi (struct sip_peer *peer) |
Check whether peer needs a new MWI notification check. | |
static const char * | domain_mode_to_text (const enum domain_mode mode) |
Print domain mode to cli. | |
static const char * | dtmfmode2str (int mode) |
Convert DTMF mode to printable string. | |
static int | expire_register (const void *data) |
Expire registration of SIP peer. | |
static void | extract_uri (struct sip_pvt *p, struct sip_request *req) |
Check Contact: URI of SIP message. | |
static const char * | find_alias (const char *name, const char *_default) |
Find compressed SIP alias. | |
static struct sip_pvt * | find_call (struct sip_request *req, struct sockaddr_in *sin, const int intended_method) |
Connect incoming SIP message to current dialog or create new dialog structure Called by handle_request, sipsock_read. | |
static const char * | find_closing_quote (const char *start, const char *lim) |
Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote. | |
static struct sip_peer * | find_peer (const char *peer, struct sockaddr_in *sin, int realtime, int devstate_only) |
Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name. | |
static struct sip_auth * | find_realm_authentication (struct sip_auth *authlist, const char *realm) |
Find authentication for a specific realm. | |
static int | find_sdp (struct sip_request *req) |
Determine whether a SIP message contains an SDP in its body. | |
static int | find_sip_method (const char *msg) |
find_sip_method: Find SIP method from header | |
static struct cfsubscription_types * | find_subscription_type (enum subscriptiontype subtype) |
Find subscription type in array. | |
static struct sip_user * | find_user (const char *name, int realtime) |
Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf). | |
static void | free_old_route (struct sip_route *route) |
Remove route from route list. | |
static int | func_check_sipdomain (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
Dial plan function to check if domain is local. | |
static int | func_header_read (struct ast_channel *chan, char *function, char *data, char *buf, size_t len) |
Read SIP header (dialplan function). | |
static int | function_sipchaninfo_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
${SIPCHANINFO()} Dialplan function - reads sip channel data | |
static int | function_sippeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
${SIPPEER()} Dialplan function - reads peer data | |
static char * | generate_random_string (char *buf, size_t size) |
Generate 32 byte random string for callid's etc. | |
static int | get_also_info (struct sip_pvt *p, struct sip_request *oreq) |
Call transfer support (old way, deprecated by the IETF)--. | |
static char * | get_body (struct sip_request *req, char *name) |
Get a specific line from the message body. | |
static char * | get_body_by_line (const char *line, const char *name, int nameLen) |
Reads one line of SIP message body. | |
static char * | get_calleridname (const char *input, char *output, size_t outputsize) |
Get caller id name from SIP headers. | |
static int | get_destination (struct sip_pvt *p, struct sip_request *oreq) |
Find out who the call is for We use the INVITE uri to find out. | |
static const char * | get_header (const struct sip_request *req, const char *name) |
Get header from SIP request. | |
static char * | get_in_brackets (char *tmp) |
Pick out text in brackets from character string. | |
static int | get_msg_text (char *buf, int len, struct sip_request *req) |
Get text out of a SIP MESSAGE packet. | |
static int | get_rdnis (struct sip_pvt *p, struct sip_request *oreq) |
Get referring dnis. | |
static int | get_refer_info (struct sip_pvt *transferer, struct sip_request *outgoing_req) |
Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure. | |
static int | get_rpid_num (const char *input, char *output, int maxlen) |
Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found. | |
static const char * | get_sdp (struct sip_request *req, const char *name) |
Get a line from an SDP message body. | |
static const char * | get_sdp_iterate (int *start, struct sip_request *req, const char *name) |
Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number. | |
static struct sip_pvt * | get_sip_pvt_byid_locked (const char *callid, const char *totag, const char *fromtag) |
Lock interface lock and find matching pvt lock. | |
static const char * | gettag (const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize) |
Get tag from packet. | |
static int | handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v) |
Handle flag-type options common to configuration of devices - users and peers. | |
static int | handle_invite_replaces (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin) |
Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. | |
static int | handle_request (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock) |
Handle incoming SIP requests (methods). | |
static int | handle_request_bye (struct sip_pvt *p, struct sip_request *req) |
Handle incoming BYE request. | |
static int | handle_request_cancel (struct sip_pvt *p, struct sip_request *req) |
Handle incoming CANCEL request. | |
static void | handle_request_info (struct sip_pvt *p, struct sip_request *req) |
Receive SIP INFO Message. | |
static int | handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, char *e, int *nounlock) |
Handle incoming INVITE request. | |
static int | handle_request_message (struct sip_pvt *p, struct sip_request *req) |
Handle incoming MESSAGE request. | |
static int | handle_request_notify (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e) |
Handle incoming notifications. | |
static int | handle_request_options (struct sip_pvt *p, struct sip_request *req) |
Handle incoming OPTIONS request. | |
static int | handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, int *nounlock) |
static int | handle_request_register (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, char *e) |
Handle incoming REGISTER request. | |
static int | handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e) |
Handle incoming SUBSCRIBE request. | |
static void | handle_response (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
Handle SIP response in dialogue. | |
static void | handle_response_invite (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno) |
Handle SIP response to INVITE dialogue. | |
static void | handle_response_peerpoke (struct sip_pvt *p, int resp, struct sip_request *req) |
Handle qualification responses (OPTIONS). | |
static void | handle_response_refer (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno) |
static int | handle_response_register (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
Handle responses on REGISTER to services. | |
static const char * | hangup_cause2sip (int cause) |
Convert Asterisk hangup causes to SIP codes. | |
static int | hangup_sip2cause (int cause) |
Convert SIP hangup causes to Asterisk hangup causes. | |
static int | init_req (struct sip_request *req, int sipmethod, const char *recip) |
Initialize SIP request. | |
static int | init_resp (struct sip_request *resp, const char *msg) |
Initialize SIP response, based on SIP request. | |
static void | initialize_initreq (struct sip_pvt *p, struct sip_request *req) |
Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog. | |
static void | initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod) |
Initiate new SIP request to peer/user. | |
static const char * | insecure2str (int port, int invite) |
Convert Insecure setting to printable string. | |
static void | list_route (struct sip_route *route) |
List all routes - mostly for debugging. | |
static int | load_module (void) |
PBX load module - initialization. | |
static int | local_attended_transfer (struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno) |
Find all call legs and bridge transferee with target called from handle_request_refer. | |
static int | lws2sws (char *msgbuf, int len) |
Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled. | |
static void | make_our_tag (char *tagbuf, size_t len) |
Make our SIP dialog tag. | |
static int | manager_sip_show_peer (struct mansession *s, const struct message *m) |
Show SIP peers in the manager API. | |
static int | manager_sip_show_peers (struct mansession *s, const struct message *m) |
Show SIP peers in the manager API. | |
static int | method_match (enum sipmethod id, const char *name) |
returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send | |
static char * | nat2str (int nat) |
Convert NAT setting to text string. | |
static void | parse_copy (struct sip_request *dst, const struct sip_request *src) |
Copy SIP request, parse it. | |
static void | parse_moved_contact (struct sip_pvt *p, struct sip_request *req) |
Parse 302 Moved temporalily response. | |
static int | parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req) |
Save contact header for 200 OK on INVITE. | |
static enum parse_register_result | parse_register_contact (struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req) |
Parse contact header and save registration (peer registration). | |
static int | parse_request (struct sip_request *req) |
Parse a SIP message. | |
static unsigned int | parse_sip_options (struct sip_pvt *pvt, const char *supported) |
Parse supported header in incoming packet. | |
static int | peer_status (struct sip_peer *peer, char *status, int statuslen) |
Report Peer status in character string. | |
static void | print_codec_to_cli (int fd, struct ast_codec_pref *pref) |
Print codec list from preference to CLI/manager. | |
static void | print_group (int fd, ast_group_t group, int crlf) |
Print call group and pickup group. | |
static void | process_request_queue (struct sip_pvt *p, int *recount, int *nounlock) |
static int | process_sdp (struct sip_pvt *p, struct sip_request *req) |
Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp(). | |
static int | queue_request (struct sip_pvt *p, const struct sip_request *req) |
static struct sip_peer * | realtime_peer (const char *newpeername, struct sockaddr_in *sin, int devstate_only) |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf | |
static void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey) |
Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups. | |
static struct sip_user * | realtime_user (const char *username) |
Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped). | |
static void | receive_message (struct sip_pvt *p, struct sip_request *req) |
Receive SIP MESSAGE method messages. | |
static char * | referstatus2str (enum referstatus rstatus) |
Convert transfer status to string. | |
static void | reg_source_db (struct sip_peer *peer) |
Get registration details from Asterisk DB. | |
static void | register_peer_exten (struct sip_peer *peer, int onoff) |
Automatically add peer extension to dial plan. | |
static enum check_auth_result | register_verify (struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri) |
Verify registration of user
| |
static char * | regstate2str (enum sipregistrystate regstate) |
Convert registration state status to string. | |
static int | reload (void) |
Part of Asterisk module interface. | |
static int | reload_config (enum channelreloadreason reason) |
Re-read SIP.conf config file. | |
static int | reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len) |
reply to authentication for outbound registrations | |
static int | reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch) |
Initialize a SIP request message (not the initial one in a dialog). | |
static int | respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Prepare SIP response packet. | |
static int | restart_monitor (void) |
Start the channel monitor thread. | |
static int | retrans_pkt (const void *data) |
Retransmit SIP message if no answer (Called from scheduler). | |
static int | scheduler_process_request_queue (const void *data) |
static int | send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
Send SIP Request to the other part of the dialogue. | |
static int | send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
Transmit response on SIP request. | |
static int | set_address_from_contact (struct sip_pvt *pvt) |
Change the other partys IP address based on given contact. | |
static void | set_destination (struct sip_pvt *p, char *uri) |
Set destination from SIP URI. | |
static void | set_insecure_flags (struct ast_flags *flags, const char *value, int lineno) |
Parse the "insecure" setting from sip.conf or from realtime. | |
static void | set_peer_defaults (struct sip_peer *peer) |
Set peer defaults before configuring specific configurations. | |
static int | sip_addheader (struct ast_channel *chan, void *data) |
Add a SIP header to an outbound INVITE. | |
static int | sip_addrcmp (char *name, struct sockaddr_in *sin) |
Support routine for find_peer. | |
static struct sip_pvt * | sip_alloc (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method) |
Allocate SIP_PVT structure and set defaults. | |
static void | sip_alreadygone (struct sip_pvt *dialog) |
static int | sip_answer (struct ast_channel *ast) |
sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface | |
static int | sip_call (struct ast_channel *ast, char *dest, int timeout) |
Initiate SIP call from PBX used from the dial() application. | |
static int | sip_cancel_destroy (struct sip_pvt *p) |
Cancel destruction of SIP dialog. | |
static int | sip_debug_test_addr (const struct sockaddr_in *addr) |
See if we pass debug IP filter. | |
static int | sip_debug_test_pvt (struct sip_pvt *p) |
Test PVT for debugging output. | |
static void | sip_destroy (struct sip_pvt *p) |
Destroy SIP call structure. | |
static void | sip_destroy_peer (struct sip_peer *peer) |
Destroy peer object from memory. | |
static void | sip_destroy_user (struct sip_user *user) |
Remove user object from in-memory storage. | |
static int | sip_devicestate (void *data) |
Part of PBX channel interface. | |
static int | sip_do_debug (int fd, int argc, char *argv[]) |
Turn on SIP debugging (CLI command). | |
static int | sip_do_debug_deprecated (int fd, int argc, char *argv[]) |
static int | sip_do_debug_ip (int fd, int argc, char *argv[]) |
Enable SIP Debugging in CLI. | |
static int | sip_do_debug_peer (int fd, int argc, char *argv[]) |
sip_do_debug_peer: Turn on SIP debugging with peer mask | |
static int | sip_do_history (int fd, int argc, char *argv[]) |
Enable SIP History logging (CLI). | |
static int | sip_do_reload (enum channelreloadreason reason) |
Reload module. | |
static int | sip_dtmfmode (struct ast_channel *chan, void *data) |
Set the DTMFmode for an outbound SIP call (application). | |
static void | sip_dump_history (struct sip_pvt *dialog) |
Dump SIP history to debug log file at end of lifespan for SIP dialog. | |
static int | sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links | |
static int | sip_get_codec (struct ast_channel *chan) |
Return SIP UA's codec (part of the RTP interface). | |
static enum ast_rtp_get_result | sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
Returns null if we can't reinvite audio (part of RTP interface). | |
static struct ast_udptl * | sip_get_udptl_peer (struct ast_channel *chan) |
static enum ast_rtp_get_result | sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
Returns null if we can't reinvite video (part of RTP interface). | |
static int | sip_handle_t38_reinvite (struct ast_channel *chan, struct sip_pvt *pvt, int reinvite) |
Handle T38 reinvite. | |
static int | sip_hangup (struct ast_channel *ast) |
sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup | |
static int | sip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen) |
Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc. | |
static const char * | sip_nat_mode (const struct sip_pvt *p) |
Display SIP nat mode. | |
static struct ast_channel * | sip_new (struct sip_pvt *i, int state, const char *title) |
Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels. | |
static int | sip_no_debug (int fd, int argc, char *argv[]) |
Disable SIP Debugging in CLI. | |
static int | sip_no_debug_deprecated (int fd, int argc, char *argv[]) |
static int | sip_no_history (int fd, int argc, char *argv[]) |
Disable SIP History logging (CLI). | |
static int | sip_notify (int fd, int argc, char *argv[]) |
Cli command to send SIP notify to peer. | |
static int | sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno) |
Park a call using the subsystem in res_features.c This is executed in a separate thread. | |
static void * | sip_park_thread (void *stuff) |
Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup. | |
static void | sip_peer_hold (struct sip_pvt *p, int hold) |
Change onhold state of a peer using a pvt structure. | |
static void | sip_poke_all_peers (void) |
Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions? | |
static int | sip_poke_noanswer (const void *data) |
React to lack of answer to Qualify poke. | |
static int | sip_poke_peer (struct sip_peer *peer) |
Check availability of peer, also keep NAT open. | |
static int | sip_poke_peer_s (const void *data) |
Poke peer (send qualify to check if peer is alive and well). | |
static int | sip_prune_realtime (int fd, int argc, char *argv[]) |
Remove temporary realtime objects from memory (CLI). | |
static struct ast_frame * | sip_read (struct ast_channel *ast) |
Read SIP RTP from channel. | |
static struct sockaddr_in * | sip_real_dst (const struct sip_pvt *p) |
The real destination address for a write. | |
static int | sip_refer_allocate (struct sip_pvt *p) |
Allocate SIP refer structure. | |
static int | sip_reg_timeout (const void *data) |
Registration timeout, register again. | |
static int | sip_register (char *value, int lineno) |
Parse register=> line in sip.conf and add to registry. | |
static void | sip_registry_destroy (struct sip_registry *reg) |
Destroy registry object Objects created with the register= statement in static configuration. | |
static int | sip_reinvite_retry (const void *data) |
Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler. | |
static int | sip_reload (int fd, int argc, char *argv[]) |
Force reload of module from cli. | |
static struct ast_channel * | sip_request_call (const char *type, int format, void *data, int *cause) |
PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here. | |
static int | sip_reregister (const void *data) |
Update registration with SIP Proxy. | |
static struct ast_frame * | sip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect) |
Read RTP from network. | |
static void | sip_scheddestroy (struct sip_pvt *p, int ms) |
Schedule destruction of SIP dialog. | |
static void | sip_send_all_registers (void) |
Send all known registrations. | |
static int | sip_send_mwi_to_peer (struct sip_peer *peer) |
Send message waiting indication to alert peer that they've got voicemail. | |
static int | sip_senddigit_begin (struct ast_channel *ast, char digit) |
static int | sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration) |
Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously. | |
static int | sip_sendtext (struct ast_channel *ast, const char *text) |
Send SIP MESSAGE text within a call Called from PBX core sendtext() application. | |
static int | sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active) |
Set the RTP peer for this call. | |
static int | sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl) |
static int | sip_show_channel (int fd, int argc, char *argv[]) |
Show details of one active dialog. | |
static int | sip_show_channels (int fd, int argc, char *argv[]) |
Show active SIP channels. | |
static int | sip_show_domains (int fd, int argc, char *argv[]) |
CLI command to list local domains. | |
static int | sip_show_history (int fd, int argc, char *argv[]) |
Show history details of one dialog. | |
static int | sip_show_inuse (int fd, int argc, char *argv[]) |
CLI Command to show calls within limits set by call_limit. | |
static int | sip_show_objects (int fd, int argc, char *argv[]) |
List all allocated SIP Objects (realtime or static). | |
static int | sip_show_peer (int fd, int argc, char *argv[]) |
Show one peer in detail. | |
static int | sip_show_peers (int fd, int argc, char *argv[]) |
CLI Show Peers command. | |
static int | sip_show_registry (int fd, int argc, char *argv[]) |
Show SIP Registry (registrations with other SIP proxies. | |
static int | sip_show_settings (int fd, int argc, char *argv[]) |
List global settings for the SIP channel. | |
static int | sip_show_subscriptions (int fd, int argc, char *argv[]) |
Show active SIP subscriptions. | |
static int | sip_show_user (int fd, int argc, char *argv[]) |
Show one user in detail. | |
static int | sip_show_users (int fd, int argc, char *argv[]) |
CLI Command 'SIP Show Users'. | |
static int | sip_sipredirect (struct sip_pvt *p, const char *dest) |
Transfer call before connect with a 302 redirect. | |
static int | sip_transfer (struct ast_channel *ast, const char *dest) |
Transfer SIP call. | |
static int | sip_uri_cmp (const char *input1, const char *input2) |
static int | sip_uri_headers_cmp (const char *input1, const char *input2) |
helper routine for sip_uri_cmp | |
static int | sip_uri_params_cmp (const char *input1, const char *input2) |
helper routine for sip_uri_cmp | |
static int | sip_write (struct ast_channel *ast, struct ast_frame *frame) |
Send frame to media channel (rtp). | |
static int | sipsock_read (int *id, int fd, short events, void *ignore) |
Read data from SIP socket. | |
static void | stop_media_flows (struct sip_pvt *p) |
Immediately stop RTP, VRTP and UDPTL as applicable. | |
static const char * | subscription_type2str (enum subscriptiontype subtype) |
Show subscription type in string format. | |
static int | t38_get_rate (int t38cap) |
Get Max T.38 Transmission rate from T38 capabilities. | |
static struct sip_peer * | temp_peer (const char *name) |
Create temporary peer (used in autocreatepeer mode). | |
static void | temp_pvt_cleanup (void *) |
static void | temp_pvt_init (void) |
A per-thread temporary pvt structure. | |
static char * | transfermode2str (enum transfermodes mode) |
Convert transfer mode to text string. | |
static void | transmit_fake_auth_response (struct sip_pvt *p, struct sip_request *req, int reliable) |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers. | |
static int | transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration) |
Send SIP INFO dtmf message, see Cisco documentation on cisco.com. | |
static int | transmit_info_with_vidupdate (struct sip_pvt *p) |
Send SIP INFO with video update request. | |
static int | transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init) |
Build REFER/INVITE/OPTIONS message and transmit it. | |
static int | transmit_message_with_text (struct sip_pvt *p, const char *text) |
Transmit text with SIP MESSAGE method. | |
static int | transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten) |
Notify user of messages waiting in voicemail. | |
static int | transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate) |
Notify a transferring party of the status of transfer. | |
static int | transmit_refer (struct sip_pvt *p, const char *dest) |
Transmit SIP REFER message (initiated by the transfer() dialplan application. | |
static int | transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader) |
Transmit register to SIP proxy or UA. | |
static int | transmit_reinvite_with_sdp (struct sip_pvt *p) |
Transmit reinvite with SDP. | |
static int | transmit_reinvite_with_t38_sdp (struct sip_pvt *p) |
Transmit reinvite with T38 SDP We reinvite so that the T38 processing can take place. SIP Signalling stays with * in the path. | |
static int | transmit_request (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry). | |
static int | transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
Transmit SIP request, auth added. | |
static int | transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Transmit response, no retransmits. | |
static int | transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK. | |
static int | transmit_response_using_temp (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg) |
Transmit response, no retransmits, using a temporary pvt structure. | |
static int | transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Append Accept header, content length before transmitting response. | |
static int | transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale) |
Respond with authorization request. | |
static int | transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
Append date and content length before transmitting response. | |
static int | transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
Used for 200 OK and 183 early media. | |
static int | transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans) |
Used for 200 OK and 183 early media. | |
static int | transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported) |
Transmit response, no retransmits. | |
static int | transmit_sip_request (struct sip_pvt *p, struct sip_request *req) |
Transmit SIP request unreliably (only used in sip_notify subsystem). | |
static int | transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout) |
Used in the SUBSCRIBE notification subsystem. | |
static void | try_suggested_sip_codec (struct sip_pvt *p) |
Try setting codec suggested by the SIP_CODEC channel variable. | |
static int | unload_module (void) |
PBX unload module API. | |
static int | update_call_counter (struct sip_pvt *fup, int event) |
update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted. | |
static void | update_peer (struct sip_peer *p, int expiry) |
Update peer data in database (if used). | |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Session Initiation Protocol (SIP)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, .reload = reload, } |
static struct in_addr | __ourip |
static int | allow_external_domains |
static int | apeerobjs = 0 |
static char * | app_dtmfmode = "SIPDtmfMode" |
static char * | app_sipaddheader = "SIPAddHeader" |
static const struct ast_module_info * | ast_module_info = &__mod_info |
static struct sip_auth * | authl = NULL |
static int | autocreatepeer |
static struct sockaddr_in | bindaddr = { 0, } |
static struct ast_threadstorage | check_auth_buf = { .once = PTHREAD_ONCE_INIT , .key_init = check_auth_buf_init , } |
static struct ast_custom_function | checksipdomain_function |
static struct ast_cli_entry | cli_sip [] |
static struct ast_cli_entry | cli_sip_debug_deprecated |
static struct ast_cli_entry | cli_sip_no_debug_deprecated |
static int | compactheaders |
static const char | config [] = "sip.conf" |
static char | debug_usage [] |
static struct sockaddr_in | debugaddr |
static char | default_callerid [AST_MAX_EXTENSION] |
static char | default_context [AST_MAX_CONTEXT] |
static int | default_expiry = DEFAULT_DEFAULT_EXPIRY |
static char | default_fromdomain [AST_MAX_EXTENSION] |
static struct ast_jb_conf | default_jbconf |
Global jitterbuffer configuration - by default, jb is disabled. | |
static char | default_language [MAX_LANGUAGE] |
static int | default_maxcallbitrate |
static char | default_mohinterpret [MAX_MUSICCLASS] |
static char | default_mohsuggest [MAX_MUSICCLASS] |
static char | default_notifymime [AST_MAX_EXTENSION] |
static struct ast_codec_pref | default_prefs |
static int | default_qualify |
static char | default_subscribecontext [AST_MAX_CONTEXT] |
static char | default_vmexten [AST_MAX_EXTENSION] |
static char * | descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" |
static char * | descrip_sipaddheader |
static int | dumphistory |
static int | expiry = DEFAULT_EXPIRY |
static time_t | externexpire = 0 |
static char | externhost [MAXHOSTNAMELEN] |
static struct sockaddr_in | externip |
static int | externrefresh = 10 |
static int | global_allowguest |
static int | global_allowsubscribe |
static enum transfermodes | global_allowtransfer |
static int | global_alwaysauthreject |
static int | global_autoframing |
static int | global_callevents |
static int | global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 |
Codecs that we support by default:. | |
static struct ast_ha * | global_contact_ha = NULL |
Global list of addresses dynamic peers are not allowed to use. | |
static int | global_directrtpsetup |
static int | global_dynamic_exclude_static = 0 |
static struct ast_flags | global_flags [2] = {{0}} |
static struct ast_jb_conf | global_jbconf |
static int | global_limitonpeers |
static int | global_matchexterniplocally |
static int | global_mwitime |
static int | global_notifyhold |
static int | global_notifyringing |
static char | global_realm [MAXHOSTNAMELEN] |
static int | global_reg_timeout |
static int | global_regattempts_max |
static char | global_regcontext [AST_MAX_CONTEXT] |
static int | global_relaxdtmf |
static int | global_rtautoclear |
static int | global_rtpholdtimeout |
static int | global_rtpkeepalive |
static int | global_rtptimeout |
static int | global_t1min |
static int | global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 |
static unsigned int | global_tos_audio |
static unsigned int | global_tos_sip |
static unsigned int | global_tos_video |
static char | global_useragent [AST_MAX_EXTENSION] |
static char | history_usage [] |
static struct sip_pvt * | iflist |
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe | |
static ast_mutex_t | iflock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
Protect the SIP dialog list (of sip_pvt's). | |
static struct io_context * | io |
static struct ast_ha * | localaddr |
static char | mandescr_show_peer [] |
static char | mandescr_show_peers [] |
static int | max_expiry = DEFAULT_MAX_EXPIRY |
static int | min_expiry = DEFAULT_MIN_EXPIRY |
static pthread_t | monitor_thread = AST_PTHREADT_NULL |
This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
static ast_mutex_t | monlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static ast_mutex_t | netlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
static char | no_debug_usage [] |
static char | no_history_usage [] |
static const char | notify_config [] = "sip_notify.conf" |
static struct ast_config * | notify_types |
static char | notify_usage [] |
static int | ourport |
static struct sockaddr_in | outboundproxyip |
static int | pedanticsipchecking |
static struct ast_peer_list | peerl |
The peer list: Peers and Friends. | |
static char | prune_realtime_usage [] |
static int | recordhistory |
static struct c_referstatusstring | referstatusstrings [] |
static struct ast_register_list | regl |
The register list: Other SIP proxys we register with and place calls to. | |
static int | regobjs = 0 |
static int | rpeerobjs = 0 |
static int | ruserobjs = 0 |
static struct sched_context * | sched |
static char | show_channel_usage [] |
static char | show_channels_usage [] |
static char | show_domains_usage [] |
static char | show_history_usage [] |
static char | show_inuse_usage [] |
static char | show_objects_usage [] |
static char | show_peer_usage [] |
static char | show_peers_usage [] |
static char | show_reg_usage [] |
static char | show_settings_usage [] |
static char | show_subscriptions_usage [] |
static char | show_user_usage [] |
static char | show_users_usage [] |
static struct ast_custom_function | sip_header_function |
static struct cfsip_methods | sip_methods [] |
static struct cfsip_options | sip_options [] |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. | |
static ast_mutex_t | sip_reload_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static char | sip_reload_usage [] |
static int | sip_reloading = FALSE |
static enum channelreloadreason | sip_reloadreason |
static struct ast_rtp_protocol | sip_rtp |
Interface structure with callbacks used to connect to RTP module. | |
static struct ast_channel_tech | sip_tech |
Definition of this channel for PBX channel registration. | |
static struct ast_channel_tech | sip_tech_info |
This version of the sip channel tech has no send_digit_begin callback. This is for use with channels using SIP INFO DTMF so that the core knows that the channel doesn't want DTMF BEGIN frames. | |
static struct ast_udptl_protocol | sip_udptl |
Interface structure with callbacks used to connect to UDPTL module. | |
static struct ast_custom_function | sipchaninfo_function |
Structure to declare a dialplan function: SIPCHANINFO. | |
ast_custom_function | sippeer_function |
Structure to declare a dialplan function: SIPPEER. | |
static int | sipsock = -1 |
static int * | sipsock_read_id |
static int | 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 1860 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 |
#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(), and sip_send_mwi_to_peer().
#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 1036 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 1034 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 6578 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(), 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(), and register_verify().
#define SIP_PKT_IGNORE_REQ (1 << 4) |
#define SIP_PKT_IGNORE_RESP (1 << 3) |
#define SIP_PKT_WITH_TOTAG (1 << 1) |
This packet has a to-tag
Definition at line 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 1620 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 registred */ 00359 REG_STATE_REGSENT, /*!< Registration request sent */ 00360 REG_STATE_AUTHSENT, /*!< We have tried to authenticate */ 00361 REG_STATE_REGISTERED, /*!< Registred 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 4334 of file chan_sip.c.
References ast_skip_blanks(), find_alias(), sip_request::header, sip_request::headers, and len().
04335 { 04336 int pass; 04337 04338 /* 04339 * Technically you can place arbitrary whitespace both before and after the ':' in 04340 * a header, although RFC3261 clearly says you shouldn't before, and place just 04341 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 04342 * a good idea to say you can do it, and if you can do it, why in the hell would. 04343 * you say you shouldn't. 04344 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 04345 * and we always allow spaces after that for compatibility. 04346 */ 04347 for (pass = 0; name && pass < 2;pass++) { 04348 int x, len = strlen(name); 04349 for (x=*start; x<req->headers; x++) { 04350 if (!strncasecmp(req->header[x], name, len)) { 04351 char *r = req->header[x] + len; /* skip name */ 04352 if (pedanticsipchecking) 04353 r = ast_skip_blanks(r); 04354 04355 if (*r == ':') { 04356 *start = x+1; 04357 return ast_skip_blanks(r+1); 04358 } 04359 } 04360 } 04361 if (pass == 0) /* Try aliases */ 04362 name = find_alias(name, NULL); 04363 } 04364 04365 /* Don't return NULL, so get_header is always a valid pointer */ 04366 return ""; 04367 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 18939 of file chan_sip.c.
static int __set_address_from_contact | ( | const char * | fullcontact, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 8201 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().
08202 { 08203 struct hostent *hp; 08204 struct ast_hostent ahp; 08205 int port; 08206 char *c, *host, *pt; 08207 char contact_buf[256]; 08208 char *contact; 08209 08210 /* Work on a copy */ 08211 ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf)); 08212 contact = contact_buf; 08213 08214 /* Make sure it's a SIP URL */ 08215 if (strncasecmp(contact, "sip:", 4)) { 08216 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 08217 } else 08218 contact += 4; 08219 08220 /* Ditch arguments */ 08221 /* XXX this code is replicated also shortly below */ 08222 08223 /* Grab host */ 08224 host = strchr(contact, '@'); 08225 if (!host) { /* No username part */ 08226 host = contact; 08227 c = NULL; 08228 } else { 08229 *host++ = '\0'; 08230 } 08231 pt = strchr(host, ':'); 08232 if (pt) { 08233 *pt++ = '\0'; 08234 port = atoi(pt); 08235 } else 08236 port = STANDARD_SIP_PORT; 08237 08238 contact = strsep(&contact, ";"); /* trim ; and beyond in username part */ 08239 host = strsep(&host, ";"); /* trim ; and beyond in host/domain part */ 08240 08241 /* XXX This could block for a long time XXX */ 08242 /* We should only do this if it's a name, not an IP */ 08243 hp = ast_gethostbyname(host, &ahp); 08244 if (!hp) { 08245 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 08246 return -1; 08247 } 08248 sin->sin_family = AF_INET; 08249 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 08250 sin->sin_port = htons(port); 08251 08252 return 0; 08253 }
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 2167 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().
02168 { 02169 struct sip_pkt *cur, *prev = NULL; 02170 02171 /* Just in case... */ 02172 char *msg; 02173 int res = FALSE; 02174 02175 msg = sip_methods[sipmethod].text; 02176 02177 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 02178 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 02179 ((ast_test_flag(cur, FLAG_RESPONSE)) || 02180 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 02181 if (!resp && (seqno == p->pendinginvite)) { 02182 if (option_debug) 02183 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 02184 p->pendinginvite = 0; 02185 } 02186 /* this is our baby */ 02187 res = TRUE; 02188 UNLINK(cur, p->packets, prev); 02189 if (cur->retransid > -1) { 02190 if (sipdebug && option_debug > 3) 02191 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 02192 } 02193 /* This odd section is designed to thwart a 02194 * race condition in the packet scheduler. There are 02195 * two conditions under which deleting the packet from the 02196 * scheduler can fail. 02197 * 02198 * 1. The packet has been removed from the scheduler because retransmission 02199 * is being attempted. The problem is that if the packet is currently attempting 02200 * retransmission and we are at this point in the code, then that MUST mean 02201 * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the 02202 * lock temporarily to allow retransmission. 02203 * 02204 * 2. The packet has reached its maximum number of retransmissions and has 02205 * been permanently removed from the packet scheduler. If this is the case, then 02206 * the packet's retransid will be set to -1. The atomicity of the setting and checking 02207 * of the retransid to -1 is ensured since in both cases p's lock is held. 02208 */ 02209 while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) { 02210 DEADLOCK_AVOIDANCE(&p->lock); 02211 } 02212 free(cur); 02213 break; 02214 } 02215 } 02216 if (option_debug) 02217 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"); 02218 }
static int __sip_autodestruct | ( | const void * | data | ) | [static] |
Kill a SIP dialog (called by scheduler).
Definition at line 2083 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().
02084 { 02085 struct sip_pvt *p = (struct sip_pvt *)data; 02086 02087 /* If this is a subscription, tell the phone that we got a timeout */ 02088 if (p->subscribed) { 02089 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 02090 p->subscribed = NONE; 02091 append_history(p, "Subscribestatus", "timeout"); 02092 if (option_debug > 2) 02093 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>"); 02094 return 10000; /* Reschedule this destruction so that we know that it's gone */ 02095 } 02096 02097 /* If there are packets still waiting for delivery, delay the destruction */ 02098 /* via bug 12101, the two usages of SIP_NEEDDESTROY in the following block 02099 * of code make a sort of "safety relief valve", that allows sip channels 02100 * that were created via INVITE, then thru some sequence were CANCELED, 02101 * to die, rather than infinitely be rescheduled */ 02102 if (p->packets && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 02103 if (option_debug > 2) 02104 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>"); 02105 append_history(p, "ReliableXmit", "timeout"); 02106 if (p->method == SIP_CANCEL || p->method == SIP_BYE) { 02107 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 02108 } 02109 return 10000; 02110 } 02111 02112 /* If we're destroying a subscription, dereference peer object too */ 02113 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 02114 ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer); 02115 02116 /* Reset schedule ID */ 02117 p->autokillid = -1; 02118 02119 if (option_debug) 02120 ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid); 02121 append_history(p, "AutoDestroy", "%s", p->callid); 02122 if (p->owner) { 02123 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 02124 ast_queue_hangup(p->owner); 02125 } else if (p->refer && !ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 02126 if (option_debug > 2) 02127 ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid); 02128 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 02129 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 02130 } else 02131 sip_destroy(p); 02132 return 0; 02133 }
static int __sip_destroy | ( | struct sip_pvt * | p, | |
int | lockowner | |||
) | [static] |
Execute destruction of SIP dialog structure, release memory.
Definition at line 3102 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().
03103 { 03104 struct sip_pvt *cur, *prev = NULL; 03105 struct sip_pkt *cp; 03106 struct sip_request *req; 03107 03108 /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */ 03109 if (p->rtp && ast_rtp_get_bridged(p->rtp)) { 03110 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03111 return -1; 03112 } 03113 03114 if (p->vrtp && ast_rtp_get_bridged(p->vrtp)) { 03115 ast_verbose("Bridge still active. Delaying destroy of SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03116 return -1; 03117 } 03118 03119 if (sip_debug_test_pvt(p) || option_debug > 2) 03120 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 03121 03122 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03123 update_call_counter(p, DEC_CALL_LIMIT); 03124 if (option_debug > 1) 03125 ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 03126 } 03127 03128 /* Unlink us from the owner if we have one */ 03129 if (p->owner) { 03130 if (lockowner) 03131 ast_channel_lock(p->owner); 03132 if (option_debug) 03133 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 03134 p->owner->tech_pvt = NULL; 03135 /* Make sure that the channel knows its backend is going away */ 03136 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 03137 if (lockowner) 03138 ast_channel_unlock(p->owner); 03139 /* Give the channel a chance to react before deallocation */ 03140 usleep(1); 03141 } 03142 03143 /* Remove link from peer to subscription of MWI */ 03144 if (p->relatedpeer) { 03145 if (p->relatedpeer->mwipvt == p) { 03146 p->relatedpeer->mwipvt = NULL; 03147 } 03148 ASTOBJ_UNREF(p->relatedpeer, sip_destroy_peer); 03149 } 03150 03151 if (dumphistory) 03152 sip_dump_history(p); 03153 03154 if (p->options) 03155 free(p->options); 03156 03157 if (p->stateid > -1) 03158 ast_extension_state_del(p->stateid, NULL); 03159 AST_SCHED_DEL(sched, p->initid); 03160 AST_SCHED_DEL(sched, p->waitid); 03161 AST_SCHED_DEL(sched, p->autokillid); 03162 AST_SCHED_DEL(sched, p->request_queue_sched_id); 03163 03164 if (p->rtp) { 03165 ast_rtp_destroy(p->rtp); 03166 } 03167 if (p->vrtp) { 03168 ast_rtp_destroy(p->vrtp); 03169 } 03170 if (p->udptl) 03171 ast_udptl_destroy(p->udptl); 03172 if (p->refer) 03173 free(p->refer); 03174 if (p->route) { 03175 free_old_route(p->route); 03176 p->route = NULL; 03177 } 03178 if (p->registry) { 03179 if (p->registry->call == p) 03180 p->registry->call = NULL; 03181 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 03182 } 03183 03184 /* Clear history */ 03185 if (p->history) { 03186 struct sip_history *hist; 03187 while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) { 03188 free(hist); 03189 p->history_entries--; 03190 } 03191 free(p->history); 03192 p->history = NULL; 03193 } 03194 03195 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 03196 ast_free(req); 03197 } 03198 03199 for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) { 03200 if (cur == p) { 03201 UNLINK(cur, iflist, prev); 03202 break; 03203 } 03204 } 03205 if (!cur) { 03206 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 03207 return 0; 03208 } 03209 03210 /* remove all current packets in this dialog */ 03211 while((cp = p->packets)) { 03212 p->packets = p->packets->next; 03213 AST_SCHED_DEL(sched, cp->retransid); 03214 free(cp); 03215 } 03216 if (p->chanvars) { 03217 ast_variables_destroy(p->chanvars); 03218 p->chanvars = NULL; 03219 } 03220 ast_mutex_destroy(&p->lock); 03221 03222 ast_string_field_free_memory(p); 03223 03224 free(p); 03225 return 0; 03226 }
static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 7634 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
07635 { 07636 int res; 07637 07638 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 07639 return res; 07640 }
static void __sip_pretend_ack | ( | struct sip_pvt * | p | ) | [static] |
Pretend to ack all packets called with p locked.
Definition at line 2222 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().
02223 { 02224 struct sip_pkt *cur = NULL; 02225 02226 while (p->packets) { 02227 int method; 02228 if (cur == p->packets) { 02229 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 02230 return; 02231 } 02232 cur = p->packets; 02233 method = (cur->method) ? cur->method : find_sip_method(cur->data); 02234 __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method); 02235 } 02236 }
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 2036 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().
02037 { 02038 struct sip_pkt *pkt; 02039 int siptimer_a = DEFAULT_RETRANS; 02040 int xmitres = 0; 02041 02042 if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) 02043 return AST_FAILURE; 02044 memcpy(pkt->data, data, len); 02045 pkt->method = sipmethod; 02046 pkt->packetlen = len; 02047 pkt->next = p->packets; 02048 pkt->owner = p; 02049 pkt->seqno = seqno; 02050 if (resp) 02051 ast_set_flag(pkt, FLAG_RESPONSE); 02052 pkt->data[len] = '\0'; 02053 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 02054 pkt->retransid = -1; 02055 if (fatal) 02056 ast_set_flag(pkt, FLAG_FATAL); 02057 if (pkt->timer_t1) 02058 siptimer_a = pkt->timer_t1 * 2; 02059 02060 if (option_debug > 3 && sipdebug) 02061 ast_log(LOG_DEBUG, "*** SIP TIMER: Initializing retransmit timer on packet: Id #%d\n", pkt->retransid); 02062 pkt->retransid = -1; 02063 pkt->next = p->packets; 02064 p->packets = pkt; 02065 if (sipmethod == SIP_INVITE) { 02066 /* Note this is a pending invite */ 02067 p->pendinginvite = seqno; 02068 } 02069 02070 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 02071 02072 if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */ 02073 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 02074 return AST_FAILURE; 02075 } else { 02076 /* Schedule retransmission */ 02077 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 02078 return AST_SUCCESS; 02079 } 02080 }
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 2239 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().
02240 { 02241 struct sip_pkt *cur; 02242 int res = -1; 02243 02244 for (cur = p->packets; cur; cur = cur->next) { 02245 if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp && 02246 (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) { 02247 /* this is our baby */ 02248 if (cur->retransid > -1) { 02249 if (option_debug > 3 && sipdebug) 02250 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 02251 } 02252 AST_SCHED_DEL(sched, cur->retransid); 02253 res = 0; 02254 break; 02255 } 02256 } 02257 if (option_debug) 02258 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"); 02259 return res; 02260 }
static int __sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[], | |||
int | subscriptions | |||
) | [static] |
SIP show channels CLI (main function).
Definition at line 11035 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().
11036 { 11037 #define FORMAT3L "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %6d\n" 11038 #define FORMAT3H "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s %-6s\n" 11039 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-15.15s %-7.7s %-15.15s\n" 11040 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n" 11041 struct sip_pvt *cur; 11042 int numchans = 0; 11043 char *referstatus = NULL; 11044 11045 if (argc != 3) 11046 return RESULT_SHOWUSAGE; 11047 ast_mutex_lock(&iflock); 11048 cur = iflist; 11049 if (!subscriptions) 11050 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 11051 else 11052 ast_cli(fd, FORMAT3H, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry"); 11053 for (; cur; cur = cur->next) { 11054 referstatus = ""; 11055 if (cur->refer) { /* SIP transfer in progress */ 11056 referstatus = referstatus2str(cur->refer->status); 11057 } 11058 if (cur->subscribed == NONE && !subscriptions) { 11059 char formatbuf[SIPBUFSIZE/2]; 11060 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 11061 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 11062 cur->callid, 11063 cur->ocseq, cur->icseq, 11064 ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0), 11065 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 11066 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 11067 cur->lastmsg , 11068 referstatus 11069 ); 11070 numchans++; 11071 } 11072 if (cur->subscribed != NONE && subscriptions) { 11073 ast_cli(fd, FORMAT3L, ast_inet_ntoa(cur->sa.sin_addr), 11074 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 11075 cur->callid, 11076 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 11077 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 11078 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 11079 subscription_type2str(cur->subscribed), 11080 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>", 11081 cur->expiry 11082 ); 11083 numchans++; 11084 } 11085 } 11086 ast_mutex_unlock(&iflock); 11087 if (!subscriptions) 11088 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 11089 else 11090 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 11091 return RESULT_SUCCESS; 11092 #undef FORMAT 11093 #undef FORMAT2 11094 #undef FORMAT3 11095 }
static int __sip_xmit | ( | struct sip_pvt * | p, | |
char * | data, | |||
int | len | |||
) | [static] |
Transmit SIP message.
Definition at line 1787 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), errno, LOG_WARNING, sip_real_dst(), sipsock, and XMIT_ERROR.
Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response().
01788 { 01789 int res; 01790 const struct sockaddr_in *dst = sip_real_dst(p); 01791 res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)); 01792 01793 if (res == -1) { 01794 switch (errno) { 01795 case EBADF: /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */ 01796 case EHOSTUNREACH: /* Host can't be reached */ 01797 case ENETDOWN: /* Inteface down */ 01798 case ENETUNREACH: /* Network failure */ 01799 case ECONNREFUSED: /* ICMP port unreachable */ 01800 res = XMIT_ERROR; /* Don't bother with trying to transmit again */ 01801 } 01802 } 01803 if (res != len) 01804 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)); 01805 return res; 01806 }
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 6169 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().
06170 { 06171 struct sip_request resp; 06172 int seqno = 0; 06173 06174 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06175 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06176 return -1; 06177 } 06178 respprep(&resp, p, msg, req); 06179 add_header_contentLength(&resp, 0); 06180 /* If we are cancelling an incoming invite for some reason, add information 06181 about the reason why we are doing this in clear text */ 06182 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 06183 char buf[10]; 06184 06185 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 06186 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 06187 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 06188 } 06189 return send_response(p, &resp, reliable, seqno); 06190 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 18939 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 10593 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().
10594 { 10595 char status[30] = ""; 10596 char cbuf[256]; 10597 struct sip_peer *peer; 10598 char codec_buf[512]; 10599 struct ast_codec_pref *pref; 10600 struct ast_variable *v; 10601 struct sip_auth *auth; 10602 int x = 0, codec = 0, load_realtime; 10603 int realtimepeers; 10604 10605 realtimepeers = ast_check_realtime("sippeers"); 10606 10607 if (argc < 4) 10608 return RESULT_SHOWUSAGE; 10609 10610 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10611 peer = find_peer(argv[3], NULL, load_realtime, 0); 10612 if (s) { /* Manager */ 10613 if (peer) { 10614 const char *id = astman_get_header(m,"ActionID"); 10615 10616 astman_append(s, "Response: Success\r\n"); 10617 if (!ast_strlen_zero(id)) 10618 astman_append(s, "ActionID: %s\r\n",id); 10619 } else { 10620 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]); 10621 astman_send_error(s, m, cbuf); 10622 return 0; 10623 } 10624 } 10625 if (peer && type==0 ) { /* Normal listing */ 10626 ast_cli(fd,"\n\n"); 10627 ast_cli(fd, " * Name : %s\n", peer->name); 10628 if (realtimepeers) { /* Realtime is enabled */ 10629 ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 10630 } 10631 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 10632 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 10633 for (auth = peer->auth; auth; auth = auth->next) { 10634 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 10635 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 10636 } 10637 ast_cli(fd, " Context : %s\n", peer->context); 10638 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 10639 ast_cli(fd, " Language : %s\n", peer->language); 10640 if (!ast_strlen_zero(peer->accountcode)) 10641 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 10642 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 10643 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 10644 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 10645 if (!ast_strlen_zero(peer->fromuser)) 10646 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 10647 if (!ast_strlen_zero(peer->fromdomain)) 10648 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 10649 ast_cli(fd, " Callgroup : "); 10650 print_group(fd, peer->callgroup, 0); 10651 ast_cli(fd, " Pickupgroup : "); 10652 print_group(fd, peer->pickupgroup, 0); 10653 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 10654 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 10655 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 10656 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 10657 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 10658 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 10659 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 10660 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 10661 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))); 10662 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10663 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 10664 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 10665 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10666 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 10667 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 10668 #endif 10669 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 10670 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 10671 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 10672 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 10673 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 10674 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 10675 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10676 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10677 10678 /* - is enumerated */ 10679 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10680 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 10681 ast_cli(fd, " ToHost : %s\n", peer->tohost); 10682 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)); 10683 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 10684 if (!ast_strlen_zero(global_regcontext)) 10685 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 10686 ast_cli(fd, " Def. Username: %s\n", peer->username); 10687 ast_cli(fd, " SIP Options : "); 10688 if (peer->sipoptions) { 10689 int lastoption = -1; 10690 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10691 if (sip_options[x].id != lastoption) { 10692 if (peer->sipoptions & sip_options[x].id) 10693 ast_cli(fd, "%s ", sip_options[x].text); 10694 lastoption = x; 10695 } 10696 } 10697 } else 10698 ast_cli(fd, "(none)"); 10699 10700 ast_cli(fd, "\n"); 10701 ast_cli(fd, " Codecs : "); 10702 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10703 ast_cli(fd, "%s\n", codec_buf); 10704 ast_cli(fd, " Codec Order : ("); 10705 print_codec_to_cli(fd, &peer->prefs); 10706 ast_cli(fd, ")\n"); 10707 10708 ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No"); 10709 ast_cli(fd, " Status : "); 10710 peer_status(peer, status, sizeof(status)); 10711 ast_cli(fd, "%s\n",status); 10712 ast_cli(fd, " Useragent : %s\n", peer->useragent); 10713 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 10714 if (peer->chanvars) { 10715 ast_cli(fd, " Variables :\n"); 10716 for (v = peer->chanvars ; v ; v = v->next) 10717 ast_cli(fd, " %s = %s\n", v->name, v->value); 10718 } 10719 ast_cli(fd,"\n"); 10720 ASTOBJ_UNREF(peer,sip_destroy_peer); 10721 } else if (peer && type == 1) { /* manager listing */ 10722 char buf[256]; 10723 astman_append(s, "Channeltype: SIP\r\n"); 10724 astman_append(s, "ObjectName: %s\r\n", peer->name); 10725 astman_append(s, "ChanObjectType: peer\r\n"); 10726 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 10727 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 10728 astman_append(s, "Context: %s\r\n", peer->context); 10729 astman_append(s, "Language: %s\r\n", peer->language); 10730 if (!ast_strlen_zero(peer->accountcode)) 10731 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 10732 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 10733 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 10734 if (!ast_strlen_zero(peer->fromuser)) 10735 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 10736 if (!ast_strlen_zero(peer->fromdomain)) 10737 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 10738 astman_append(s, "Callgroup: "); 10739 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup)); 10740 astman_append(s, "Pickupgroup: "); 10741 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup)); 10742 astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox); 10743 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 10744 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 10745 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 10746 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 10747 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 10748 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 10749 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 10750 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))); 10751 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10752 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 10753 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 10754 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 10755 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 10756 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 10757 10758 /* - is enumerated */ 10759 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10760 astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg); 10761 astman_append(s, "ToHost: %s\r\n", peer->tohost); 10762 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)); 10763 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)); 10764 astman_append(s, "Default-Username: %s\r\n", peer->username); 10765 if (!ast_strlen_zero(global_regcontext)) 10766 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 10767 astman_append(s, "Codecs: "); 10768 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10769 astman_append(s, "%s\r\n", codec_buf); 10770 astman_append(s, "CodecOrder: "); 10771 pref = &peer->prefs; 10772 for(x = 0; x < 32 ; x++) { 10773 codec = ast_codec_pref_index(pref,x); 10774 if (!codec) 10775 break; 10776 astman_append(s, "%s", ast_getformatname(codec)); 10777 if (x < 31 && ast_codec_pref_index(pref,x+1)) 10778 astman_append(s, ","); 10779 } 10780 10781 astman_append(s, "\r\n"); 10782 astman_append(s, "Status: "); 10783 peer_status(peer, status, sizeof(status)); 10784 astman_append(s, "%s\r\n", status); 10785 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 10786 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 10787 if (peer->chanvars) { 10788 for (v = peer->chanvars ; v ; v = v->next) { 10789 astman_append(s, "ChanVariable:\n"); 10790 astman_append(s, " %s,%s\r\n", v->name, v->value); 10791 } 10792 } 10793 10794 ASTOBJ_UNREF(peer,sip_destroy_peer); 10795 10796 } else { 10797 ast_cli(fd,"Peer %s not found.\n", argv[3]); 10798 ast_cli(fd,"\n"); 10799 } 10800 10801 return RESULT_SUCCESS; 10802 }
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 10143 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().
10144 { 10145 regex_t regexbuf; 10146 int havepattern = FALSE; 10147 10148 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 10149 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 10150 10151 char name[256]; 10152 int total_peers = 0; 10153 int peers_mon_online = 0; 10154 int peers_mon_offline = 0; 10155 int peers_unmon_offline = 0; 10156 int peers_unmon_online = 0; 10157 const char *id; 10158 char idtext[256] = ""; 10159 int realtimepeers; 10160 10161 realtimepeers = ast_check_realtime("sippeers"); 10162 10163 if (s) { /* Manager - get ActionID */ 10164 id = astman_get_header(m,"ActionID"); 10165 if (!ast_strlen_zero(id)) 10166 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 10167 } 10168 10169 switch (argc) { 10170 case 5: 10171 if (!strcasecmp(argv[3], "like")) { 10172 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 10173 return RESULT_SHOWUSAGE; 10174 havepattern = TRUE; 10175 } else 10176 return RESULT_SHOWUSAGE; 10177 case 3: 10178 break; 10179 default: 10180 return RESULT_SHOWUSAGE; 10181 } 10182 10183 if (!s) /* Normal list */ 10184 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 10185 10186 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10187 char status[20] = ""; 10188 char srch[2000]; 10189 char pstatus; 10190 10191 ASTOBJ_RDLOCK(iterator); 10192 10193 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10194 ASTOBJ_UNLOCK(iterator); 10195 continue; 10196 } 10197 10198 if (!ast_strlen_zero(iterator->username) && !s) 10199 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 10200 else 10201 ast_copy_string(name, iterator->name, sizeof(name)); 10202 10203 pstatus = peer_status(iterator, status, sizeof(status)); 10204 if (pstatus == 1) 10205 peers_mon_online++; 10206 else if (pstatus == 0) 10207 peers_mon_offline++; 10208 else { 10209 if (iterator->addr.sin_port == 0) 10210 peers_unmon_offline++; 10211 else 10212 peers_unmon_online++; 10213 } 10214 10215 snprintf(srch, sizeof(srch), FORMAT, name, 10216 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10217 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10218 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10219 iterator->ha ? " A " : " ", /* permit/deny */ 10220 ntohs(iterator->addr.sin_port), status, 10221 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10222 10223 if (!s) {/* Normal CLI list */ 10224 ast_cli(fd, FORMAT, name, 10225 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 10226 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 10227 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 10228 iterator->ha ? " A " : " ", /* permit/deny */ 10229 10230 ntohs(iterator->addr.sin_port), status, 10231 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 10232 } else { /* Manager format */ 10233 /* The names here need to be the same as other channels */ 10234 astman_append(s, 10235 "Event: PeerEntry\r\n%s" 10236 "Channeltype: SIP\r\n" 10237 "ObjectName: %s\r\n" 10238 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 10239 "IPaddress: %s\r\n" 10240 "IPport: %d\r\n" 10241 "Dynamic: %s\r\n" 10242 "Natsupport: %s\r\n" 10243 "VideoSupport: %s\r\n" 10244 "ACL: %s\r\n" 10245 "Status: %s\r\n" 10246 "RealtimeDevice: %s\r\n\r\n", 10247 idtext, 10248 iterator->name, 10249 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 10250 ntohs(iterator->addr.sin_port), 10251 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 10252 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 10253 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 10254 iterator->ha ? "yes" : "no", /* permit/deny */ 10255 status, 10256 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 10257 } 10258 10259 ASTOBJ_UNLOCK(iterator); 10260 10261 total_peers++; 10262 } while(0) ); 10263 10264 if (!s) 10265 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 10266 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 10267 10268 if (havepattern) 10269 regfree(®exbuf); 10270 10271 if (total) 10272 *total = total_peers; 10273 10274 10275 return RESULT_SUCCESS; 10276 #undef FORMAT 10277 #undef FORMAT2 10278 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 15260 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.
15261 { 15262 struct ast_rtp_quality qos; 15263 struct sip_pvt *p = chan->tech_pvt; 15264 char *all = "", *parse = ast_strdupa(preparse); 15265 AST_DECLARE_APP_ARGS(args, 15266 AST_APP_ARG(param); 15267 AST_APP_ARG(type); 15268 AST_APP_ARG(field); 15269 ); 15270 AST_STANDARD_APP_ARGS(args, parse); 15271 15272 /* Sanity check */ 15273 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 15274 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 15275 return 0; 15276 } 15277 15278 if (strcasecmp(args.param, "rtpqos")) 15279 return 0; 15280 15281 /* Default arguments of audio,all */ 15282 if (ast_strlen_zero(args.type)) 15283 args.type = "audio"; 15284 if (ast_strlen_zero(args.field)) 15285 args.field = "all"; 15286 15287 memset(buf, 0, buflen); 15288 memset(&qos, 0, sizeof(qos)); 15289 15290 if (strcasecmp(args.type, "AUDIO") == 0) { 15291 all = ast_rtp_get_quality(p->rtp, &qos); 15292 } else if (strcasecmp(args.type, "VIDEO") == 0) { 15293 all = ast_rtp_get_quality(p->vrtp, &qos); 15294 } 15295 15296 if (strcasecmp(args.field, "local_ssrc") == 0) 15297 snprintf(buf, buflen, "%u", qos.local_ssrc); 15298 else if (strcasecmp(args.field, "local_lostpackets") == 0) 15299 snprintf(buf, buflen, "%u", qos.local_lostpackets); 15300 else if (strcasecmp(args.field, "local_jitter") == 0) 15301 snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0); 15302 else if (strcasecmp(args.field, "local_count") == 0) 15303 snprintf(buf, buflen, "%u", qos.local_count); 15304 else if (strcasecmp(args.field, "remote_ssrc") == 0) 15305 snprintf(buf, buflen, "%u", qos.remote_ssrc); 15306 else if (strcasecmp(args.field, "remote_lostpackets") == 0) 15307 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 15308 else if (strcasecmp(args.field, "remote_jitter") == 0) 15309 snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0); 15310 else if (strcasecmp(args.field, "remote_count") == 0) 15311 snprintf(buf, buflen, "%u", qos.remote_count); 15312 else if (strcasecmp(args.field, "rtt") == 0) 15313 snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0); 15314 else if (strcasecmp(args.field, "all") == 0) 15315 ast_copy_string(buf, all, buflen); 15316 else { 15317 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 15318 return -1; 15319 } 15320 return 0; 15321 }
static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 2273 of file chan_sip.c.
References sip_request::data, sip_request::len, and sip_request::lines.
Referenced by send_request(), and send_response().
02274 { 02275 if (!req->lines) { 02276 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 02277 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 02278 req->len += strlen(req->data + req->len); 02279 } 02280 }
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 6374 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().
06377 { 06378 int rtp_code; 06379 struct ast_format_list fmt; 06380 06381 06382 if (debug) 06383 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 06384 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 06385 return; 06386 06387 if (p->rtp) { 06388 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 06389 fmt = ast_codec_pref_getsize(pref, codec); 06390 } 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 */ 06391 return; 06392 ast_build_string(m_buf, m_size, " %d", rtp_code); 06393 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06394 ast_rtp_lookup_mime_subtype(1, codec, 06395 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 06396 sample_rate); 06397 if (codec == AST_FORMAT_G729A) { 06398 /* Indicate that we don't support VAD (G.729 annex B) */ 06399 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 06400 } else if (codec == AST_FORMAT_G723_1) { 06401 /* Indicate that we don't support VAD (G.723.1 annex A) */ 06402 ast_build_string(a_buf, a_size, "a=fmtp:%d annexa=no\r\n", rtp_code); 06403 } else if (codec == AST_FORMAT_ILBC) { 06404 /* Add information about us using only 20/30 ms packetization */ 06405 ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 06406 } 06407 06408 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 06409 *min_packet_size = fmt.cur_ms; 06410 06411 /* Our first codec packetization processed cannot be less than zero */ 06412 if ((*min_packet_size) == 0 && fmt.cur_ms) 06413 *min_packet_size = fmt.cur_ms; 06414 }
static int add_digit | ( | struct sip_request * | req, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Add DTMF INFO tone to sip message.
Definition at line 6342 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_digit().
06343 { 06344 char tmp[256]; 06345 06346 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 06347 add_header(req, "Content-Type", "application/dtmf-relay"); 06348 add_header_contentLength(req, strlen(tmp)); 06349 add_line(req, tmp); 06350 return 0; 06351 }
static int add_header | ( | struct sip_request * | req, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Add header to SIP message.
Definition at line 5733 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.
05734 { 05735 int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */ 05736 05737 if (req->headers == SIP_MAX_HEADERS) { 05738 ast_log(LOG_WARNING, "Out of SIP header space\n"); 05739 return -1; 05740 } 05741 05742 if (req->lines) { 05743 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 05744 return -1; 05745 } 05746 05747 if (maxlen <= 0) { 05748 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 05749 return -1; 05750 } 05751 05752 req->header[req->headers] = req->data + req->len; 05753 05754 if (compactheaders) 05755 var = find_alias(var, var); 05756 05757 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 05758 req->len += strlen(req->header[req->headers]); 05759 req->headers++; 05760 05761 return 0; 05762 }
static int add_header_contentLength | ( | struct sip_request * | req, | |
int | len | |||
) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 5765 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().
05766 { 05767 char clen[10]; 05768 05769 snprintf(clen, sizeof(clen), "%d", len); 05770 return add_header(req, "Content-Length", clen); 05771 }
static int add_line | ( | struct sip_request * | req, | |
const char * | line | |||
) | [static] |
Add content (not header) to SIP message.
Definition at line 5774 of file chan_sip.c.
References ast_log(), sip_request::data, sip_request::len, sip_request::line, sip_request::lines, and SIP_MAX_LINES.
05775 { 05776 if (req->lines == SIP_MAX_LINES) { 05777 ast_log(LOG_WARNING, "Out of SIP line space\n"); 05778 return -1; 05779 } 05780 if (!req->lines) { 05781 /* Add extra empty return */ 05782 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 05783 req->len += strlen(req->data + req->len); 05784 } 05785 if (req->len >= sizeof(req->data) - 4) { 05786 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 05787 return -1; 05788 } 05789 req->line[req->lines] = req->data + req->len; 05790 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 05791 req->len += strlen(req->line[req->lines]); 05792 req->lines++; 05793 return 0; 05794 }
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 6553 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().
06556 { 06557 int rtp_code; 06558 06559 if (debug) 06560 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 06561 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 06562 return; 06563 06564 ast_build_string(m_buf, m_size, " %d", rtp_code); 06565 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06566 ast_rtp_lookup_mime_subtype(0, format, 0), 06567 sample_rate); 06568 if (format == AST_RTP_DTMF) 06569 /* Indicate we support DTMF and FLASH... */ 06570 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 06571 }
static struct sip_auth * add_realm_authentication | ( | struct sip_auth * | authlist, | |
char * | configuration, | |||
int | lineno | |||
) | [static] |
Add realm authentication in list.
Definition at line 16993 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().
16994 { 16995 char authcopy[256]; 16996 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 16997 char *stringp; 16998 struct sip_auth *a, *b, *auth; 16999 17000 if (ast_strlen_zero(configuration)) 17001 return authlist; 17002 17003 if (option_debug) 17004 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 17005 17006 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 17007 stringp = authcopy; 17008 17009 username = stringp; 17010 realm = strrchr(stringp, '@'); 17011 if (realm) 17012 *realm++ = '\0'; 17013 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 17014 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 17015 return authlist; 17016 } 17017 stringp = username; 17018 username = strsep(&stringp, ":"); 17019 if (username) { 17020 secret = strsep(&stringp, ":"); 17021 if (!secret) { 17022 stringp = username; 17023 md5secret = strsep(&stringp,"#"); 17024 } 17025 } 17026 if (!(auth = ast_calloc(1, sizeof(*auth)))) 17027 return authlist; 17028 17029 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 17030 ast_copy_string(auth->username, username, sizeof(auth->username)); 17031 if (secret) 17032 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 17033 if (md5secret) 17034 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 17035 17036 /* find the end of the list */ 17037 for (b = NULL, a = authlist; a ; b = a, a = a->next) 17038 ; 17039 if (b) 17040 b->next = auth; /* Add structure add end of list */ 17041 else 17042 authlist = auth; 17043 17044 if (option_verbose > 2) 17045 ast_verbose("Added authentication for realm %s\n", realm); 17046 17047 return authlist; 17048 17049 }
static void add_route | ( | struct sip_request * | req, | |
struct sip_route * | route | |||
) | [static] |
Add route header into request per learned route.
Definition at line 5895 of file chan_sip.c.
References add_header(), ast_copy_string(), sip_route::hop, sip_route::next, and SIPBUFSIZE.
Referenced by reqprep().
05896 { 05897 char r[SIPBUFSIZE*2], *p; 05898 int n, rem = sizeof(r); 05899 05900 if (!route) 05901 return; 05902 05903 p = r; 05904 for (;route ; route = route->next) { 05905 n = strlen(route->hop); 05906 if (rem < n+3) /* we need room for ",<route>" */ 05907 break; 05908 if (p != r) { /* add a separator after fist route */ 05909 *p++ = ','; 05910 --rem; 05911 } 05912 *p++ = '<'; 05913 ast_copy_string(p, route->hop, rem); /* cannot fail */ 05914 p += n; 05915 *p++ = '>'; 05916 rem -= (n+2); 05917 } 05918 *p = '\0'; 05919 add_header(req, "Route", r); 05920 }
static enum sip_result add_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add Session Description Protocol message.
Definition at line 6581 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.
06582 { 06583 int len = 0; 06584 int alreadysent = 0; 06585 06586 struct sockaddr_in sin; 06587 struct sockaddr_in vsin; 06588 struct sockaddr_in dest; 06589 struct sockaddr_in vdest = { 0, }; 06590 06591 /* SDP fields */ 06592 char *version = "v=0\r\n"; /* Protocol version */ 06593 char *subject = "s=session\r\n"; /* Subject of the session */ 06594 char owner[256]; /* Session owner/creator */ 06595 char connection[256]; /* Connection data */ 06596 char *stime = "t=0 0\r\n"; /* Time the session is active */ 06597 char bandwidth[256] = ""; /* Max bitrate */ 06598 char *hold; 06599 char m_audio[256]; /* Media declaration line for audio */ 06600 char m_video[256]; /* Media declaration line for video */ 06601 char a_audio[1024]; /* Attributes for audio */ 06602 char a_video[1024]; /* Attributes for video */ 06603 char *m_audio_next = m_audio; 06604 char *m_video_next = m_video; 06605 size_t m_audio_left = sizeof(m_audio); 06606 size_t m_video_left = sizeof(m_video); 06607 char *a_audio_next = a_audio; 06608 char *a_video_next = a_video; 06609 size_t a_audio_left = sizeof(a_audio); 06610 size_t a_video_left = sizeof(a_video); 06611 06612 int x; 06613 int capability; 06614 int needvideo = FALSE; 06615 int debug = sip_debug_test_pvt(p); 06616 int min_audio_packet_size = 0; 06617 int min_video_packet_size = 0; 06618 06619 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 06620 06621 if (!p->rtp) { 06622 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 06623 return AST_FAILURE; 06624 } 06625 06626 /* Set RTP Session ID and version */ 06627 if (!p->sessionid) { 06628 p->sessionid = getpid(); 06629 p->sessionversion = p->sessionid; 06630 } else 06631 p->sessionversion++; 06632 06633 /* Get our addresses */ 06634 ast_rtp_get_us(p->rtp, &sin); 06635 if (p->vrtp) 06636 ast_rtp_get_us(p->vrtp, &vsin); 06637 06638 /* Is this a re-invite to move the media out, then use the original offer from caller */ 06639 if (p->redirip.sin_addr.s_addr) { 06640 dest.sin_port = p->redirip.sin_port; 06641 dest.sin_addr = p->redirip.sin_addr; 06642 } else { 06643 dest.sin_addr = p->ourip; 06644 dest.sin_port = sin.sin_port; 06645 } 06646 06647 capability = p->jointcapability; 06648 06649 06650 if (option_debug > 1) { 06651 char codecbuf[SIPBUFSIZE]; 06652 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"); 06653 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 06654 } 06655 06656 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 06657 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 06658 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 06659 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 06660 } 06661 #endif 06662 06663 /* Check if we need video in this call */ 06664 if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 06665 if (p->vrtp) { 06666 needvideo = TRUE; 06667 if (option_debug > 1) 06668 ast_log(LOG_DEBUG, "This call needs video offers!\n"); 06669 } else if (option_debug > 1) 06670 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n"); 06671 } 06672 06673 06674 /* Ok, we need video. Let's add what we need for video and set codecs. 06675 Video is handled differently than audio since we can not transcode. */ 06676 if (needvideo) { 06677 /* Determine video destination */ 06678 if (p->vredirip.sin_addr.s_addr) { 06679 vdest.sin_addr = p->vredirip.sin_addr; 06680 vdest.sin_port = p->vredirip.sin_port; 06681 } else { 06682 vdest.sin_addr = p->ourip; 06683 vdest.sin_port = vsin.sin_port; 06684 } 06685 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 06686 06687 /* Build max bitrate string */ 06688 if (p->maxcallbitrate) 06689 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 06690 if (debug) 06691 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 06692 } 06693 06694 if (debug) 06695 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 06696 06697 /* Start building generic SDP headers */ 06698 06699 /* We break with the "recommendation" and send our IP, in order that our 06700 peer doesn't have to ast_gethostbyname() us */ 06701 06702 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 06703 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 06704 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 06705 06706 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR) 06707 hold = "a=recvonly\r\n"; 06708 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE) 06709 hold = "a=inactive\r\n"; 06710 else 06711 hold = "a=sendrecv\r\n"; 06712 06713 /* Now, start adding audio codecs. These are added in this order: 06714 - First what was requested by the calling channel 06715 - Then preferences in order from sip.conf device config for this peer/user 06716 - Then other codecs in capabilities, including video 06717 */ 06718 06719 /* Prefer the audio codec we were requested to use, first, no matter what 06720 Note that p->prefcodec can include video codecs, so mask them out 06721 */ 06722 if (capability & p->prefcodec) { 06723 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 06724 06725 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06726 &m_audio_next, &m_audio_left, 06727 &a_audio_next, &a_audio_left, 06728 debug, &min_audio_packet_size); 06729 alreadysent |= codec; 06730 } 06731 06732 /* Start by sending our preferred audio codecs */ 06733 for (x = 0; x < 32; x++) { 06734 int codec; 06735 06736 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 06737 break; 06738 06739 if (!(capability & codec)) 06740 continue; 06741 06742 if (alreadysent & codec) 06743 continue; 06744 06745 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06746 &m_audio_next, &m_audio_left, 06747 &a_audio_next, &a_audio_left, 06748 debug, &min_audio_packet_size); 06749 alreadysent |= codec; 06750 } 06751 06752 /* Now send any other common audio and video codecs, and non-codec formats: */ 06753 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 06754 if (!(capability & x)) /* Codec not requested */ 06755 continue; 06756 06757 if (alreadysent & x) /* Already added to SDP */ 06758 continue; 06759 06760 if (x <= AST_FORMAT_MAX_AUDIO) 06761 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 06762 &m_audio_next, &m_audio_left, 06763 &a_audio_next, &a_audio_left, 06764 debug, &min_audio_packet_size); 06765 else 06766 add_codec_to_sdp(p, x, 90000, 06767 &m_video_next, &m_video_left, 06768 &a_video_next, &a_video_left, 06769 debug, &min_video_packet_size); 06770 } 06771 06772 /* Now add DTMF RFC2833 telephony-event as a codec */ 06773 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 06774 if (!(p->jointnoncodeccapability & x)) 06775 continue; 06776 06777 add_noncodec_to_sdp(p, x, 8000, 06778 &m_audio_next, &m_audio_left, 06779 &a_audio_next, &a_audio_left, 06780 debug); 06781 } 06782 06783 if (option_debug > 2) 06784 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 06785 06786 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 06787 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 06788 06789 if (min_audio_packet_size) 06790 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 06791 06792 if (min_video_packet_size) 06793 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 06794 06795 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 06796 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 06797 06798 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 06799 if (needvideo) 06800 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 06801 06802 len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold); 06803 if (needvideo) /* only if video response is appropriate */ 06804 len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold); 06805 06806 add_header(resp, "Content-Type", "application/sdp"); 06807 add_header_contentLength(resp, len); 06808 add_line(resp, version); 06809 add_line(resp, owner); 06810 add_line(resp, subject); 06811 add_line(resp, connection); 06812 if (needvideo) /* only if video response is appropriate */ 06813 add_line(resp, bandwidth); 06814 add_line(resp, stime); 06815 add_line(resp, m_audio); 06816 add_line(resp, a_audio); 06817 add_line(resp, hold); 06818 if (needvideo) { /* only if video response is appropriate */ 06819 add_line(resp, m_video); 06820 add_line(resp, a_video); 06821 add_line(resp, hold); /* Repeat hold for the video stream */ 06822 } 06823 06824 /* Update lastrtprx when we send our SDP */ 06825 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 06826 06827 if (option_debug > 2) { 06828 char buf[SIPBUFSIZE]; 06829 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability)); 06830 } 06831 06832 return AST_SUCCESS; 06833 }
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 16929 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.
16930 { 16931 struct domain *d; 16932 16933 if (ast_strlen_zero(domain)) { 16934 ast_log(LOG_WARNING, "Zero length domain.\n"); 16935 return 1; 16936 } 16937 16938 if (!(d = ast_calloc(1, sizeof(*d)))) 16939 return 0; 16940 16941 ast_copy_string(d->domain, domain, sizeof(d->domain)); 16942 16943 if (!ast_strlen_zero(context)) 16944 ast_copy_string(d->context, context, sizeof(d->context)); 16945 16946 d->mode = mode; 16947 16948 AST_LIST_LOCK(&domain_list); 16949 AST_LIST_INSERT_TAIL(&domain_list, d, list); 16950 AST_LIST_UNLOCK(&domain_list); 16951 16952 if (sipdebug) 16953 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 16954 16955 return 1; 16956 }
static int add_t38_sdp | ( | struct sip_request * | resp, | |
struct sip_pvt * | p | |||
) | [static] |
Add T.38 Session Description Protocol message.
Definition at line 6453 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().
06454 { 06455 int len = 0; 06456 int x = 0; 06457 struct sockaddr_in udptlsin; 06458 char v[256] = ""; 06459 char s[256] = ""; 06460 char o[256] = ""; 06461 char c[256] = ""; 06462 char t[256] = ""; 06463 char m_modem[256]; 06464 char a_modem[1024]; 06465 char *m_modem_next = m_modem; 06466 size_t m_modem_left = sizeof(m_modem); 06467 char *a_modem_next = a_modem; 06468 size_t a_modem_left = sizeof(a_modem); 06469 struct sockaddr_in udptldest = { 0, }; 06470 int debug; 06471 06472 debug = sip_debug_test_pvt(p); 06473 len = 0; 06474 if (!p->udptl) { 06475 ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n"); 06476 return -1; 06477 } 06478 06479 if (!p->sessionid) { 06480 p->sessionid = getpid(); 06481 p->sessionversion = p->sessionid; 06482 } else 06483 p->sessionversion++; 06484 06485 /* Our T.38 end is */ 06486 ast_udptl_get_us(p->udptl, &udptlsin); 06487 06488 /* Determine T.38 UDPTL destination */ 06489 if (p->udptlredirip.sin_addr.s_addr) { 06490 udptldest.sin_port = p->udptlredirip.sin_port; 06491 udptldest.sin_addr = p->udptlredirip.sin_addr; 06492 } else { 06493 udptldest.sin_addr = p->ourip; 06494 udptldest.sin_port = udptlsin.sin_port; 06495 } 06496 06497 if (debug) 06498 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 06499 06500 /* We break with the "recommendation" and send our IP, in order that our 06501 peer doesn't have to ast_gethostbyname() us */ 06502 06503 if (debug) { 06504 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 06505 p->t38.capability, 06506 p->t38.peercapability, 06507 p->t38.jointcapability); 06508 } 06509 snprintf(v, sizeof(v), "v=0\r\n"); 06510 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr)); 06511 snprintf(s, sizeof(s), "s=session\r\n"); 06512 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr)); 06513 snprintf(t, sizeof(t), "t=0 0\r\n"); 06514 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 06515 06516 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 06517 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 06518 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 06519 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 06520 if ((x = t38_get_rate(p->t38.jointcapability))) 06521 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 06522 if ((p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) == T38FAX_FILL_BIT_REMOVAL) 06523 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval\r\n"); 06524 if ((p->t38.jointcapability & T38FAX_TRANSCODING_MMR) == T38FAX_TRANSCODING_MMR) 06525 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR\r\n"); 06526 if ((p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) == T38FAX_TRANSCODING_JBIG) 06527 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG\r\n"); 06528 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 06529 x = ast_udptl_get_local_max_datagram(p->udptl); 06530 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 06531 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 06532 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 06533 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 06534 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem); 06535 add_header(resp, "Content-Type", "application/sdp"); 06536 add_header_contentLength(resp, len); 06537 add_line(resp, v); 06538 add_line(resp, o); 06539 add_line(resp, s); 06540 add_line(resp, c); 06541 add_line(resp, t); 06542 add_line(resp, m_modem); 06543 add_line(resp, a_modem); 06544 06545 /* Update lastrtprx when we send our SDP */ 06546 p->lastrtprx = p->lastrtptx = time(NULL); 06547 06548 return 0; 06549 }
static int add_text | ( | struct sip_request * | req, | |
const char * | text | |||
) | [static] |
Add text body to SIP message.
Definition at line 6331 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_message_with_text().
06332 { 06333 /* XXX Convert \n's to \r\n's XXX */ 06334 add_header(req, "Content-Type", "text/plain"); 06335 add_header_contentLength(req, strlen(text)); 06336 add_line(req, text); 06337 return 0; 06338 }
static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 6355 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_vidupdate().
06356 { 06357 const char *xml_is_a_huge_waste_of_space = 06358 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 06359 " <media_control>\r\n" 06360 " <vc_primitive>\r\n" 06361 " <to_encoder>\r\n" 06362 " <picture_fast_update>\r\n" 06363 " </picture_fast_update>\r\n" 06364 " </to_encoder>\r\n" 06365 " </vc_primitive>\r\n" 06366 " </media_control>\r\n"; 06367 add_header(req, "Content-Type", "application/media_control+xml"); 06368 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 06369 add_line(req, xml_is_a_huge_waste_of_space); 06370 return 0; 06371 }
static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 6278 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().
06279 { 06280 char tmpdat[256]; 06281 struct tm tm; 06282 time_t t = time(NULL); 06283 06284 gmtime_r(&t, &tm); 06285 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 06286 add_header(req, "Date", tmpdat); 06287 }
static void append_history_full | ( | struct sip_pvt * | p, | |
const char * | fmt, | |||
... | ||||
) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1893 of file chan_sip.c.
References append_history_va(), ast_test_flag, sip_pvt::flags, and SIP_NO_HISTORY.
01894 { 01895 va_list ap; 01896 01897 if (!p) 01898 return; 01899 01900 if (ast_test_flag(&p->flags[0], SIP_NO_HISTORY) 01901 && !recordhistory && !dumphistory) { 01902 return; 01903 } 01904 01905 va_start(ap, fmt); 01906 append_history_va(p, fmt, ap); 01907 va_end(ap); 01908 01909 return; 01910 }
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 1866 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().
01867 { 01868 char buf[80], *c = buf; /* max history length */ 01869 struct sip_history *hist; 01870 int l; 01871 01872 vsnprintf(buf, sizeof(buf), fmt, ap); 01873 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 01874 l = strlen(buf) + 1; 01875 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) 01876 return; 01877 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 01878 free(hist); 01879 return; 01880 } 01881 memcpy(hist->event, buf, l); 01882 if (p->history_entries == MAX_HISTORY_ENTRIES) { 01883 struct sip_history *oldest; 01884 oldest = AST_LIST_REMOVE_HEAD(p->history, list); 01885 p->history_entries--; 01886 free(oldest); 01887 } 01888 AST_LIST_INSERT_TAIL(p->history, hist, list); 01889 p->history_entries++; 01890 }
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 13514 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().
13515 { 13516 if (chan && chan->_state == AST_STATE_UP) { 13517 if (ast_test_flag(chan, AST_FLAG_MOH)) 13518 ast_moh_stop(chan); 13519 else if (chan->generatordata) 13520 ast_deactivate_generator(chan); 13521 } 13522 }
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 1826 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().
01827 { 01828 struct sockaddr_in theirs, ours; 01829 01830 /* Get our local information */ 01831 ast_ouraddrfor(them, us); 01832 theirs.sin_addr = *them; 01833 ours.sin_addr = *us; 01834 01835 if (localaddr && externip.sin_addr.s_addr && 01836 (ast_apply_ha(localaddr, &theirs)) && 01837 (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) { 01838 if (externexpire && time(NULL) >= externexpire) { 01839 struct ast_hostent ahp; 01840 struct hostent *hp; 01841 01842 externexpire = time(NULL) + externrefresh; 01843 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01844 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01845 } else 01846 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01847 } 01848 *us = externip.sin_addr; 01849 if (option_debug) { 01850 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 01851 ast_inet_ntoa(*(struct in_addr *)&them->s_addr)); 01852 } 01853 } else if (bindaddr.sin_addr.s_addr) 01854 *us = bindaddr.sin_addr; 01855 return AST_SUCCESS; 01856 }
Attempt transfer of SIP call This fix for attended transfers on a local PBX.
Definition at line 13526 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.
13527 { 13528 int res = 0; 13529 struct ast_channel *peera = NULL, 13530 *peerb = NULL, 13531 *peerc = NULL, 13532 *peerd = NULL; 13533 13534 13535 /* We will try to connect the transferee with the target and hangup 13536 all channels to the transferer */ 13537 if (option_debug > 3) { 13538 ast_log(LOG_DEBUG, "Sip transfer:--------------------\n"); 13539 if (transferer->chan1) 13540 ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 13541 else 13542 ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n"); 13543 if (target->chan1) 13544 ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 13545 else 13546 ast_log(LOG_DEBUG, "-- No target first channel ---\n"); 13547 if (transferer->chan2) 13548 ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 13549 else 13550 ast_log(LOG_DEBUG, "-- No bridged call to transferee\n"); 13551 if (target->chan2) 13552 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)"); 13553 else 13554 ast_log(LOG_DEBUG, "-- No target second channel ---\n"); 13555 ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n"); 13556 } 13557 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 13558 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 13559 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 13560 peerc = transferer->chan2; /* Asterisk to Transferee */ 13561 peerd = target->chan2; /* Asterisk to Target */ 13562 if (option_debug > 2) 13563 ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n"); 13564 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 13565 peera = target->chan1; /* Transferer to PBX -> target channel */ 13566 peerb = transferer->chan1; /* Transferer to IVR*/ 13567 peerc = target->chan2; /* Asterisk to Target */ 13568 peerd = transferer->chan2; /* Nothing */ 13569 if (option_debug > 2) 13570 ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n"); 13571 } 13572 13573 if (peera && peerb && peerc && (peerb != peerc)) { 13574 ast_quiet_chan(peera); /* Stop generators */ 13575 ast_quiet_chan(peerb); 13576 ast_quiet_chan(peerc); 13577 if (peerd) 13578 ast_quiet_chan(peerd); 13579 13580 if (option_debug > 3) 13581 ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 13582 if (ast_channel_masquerade(peerb, peerc)) { 13583 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 13584 res = -1; 13585 } else 13586 ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n"); 13587 return res; 13588 } else { 13589 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 13590 if (transferer->chan1) 13591 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 13592 if (target->chan1) 13593 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 13594 return -2; 13595 } 13596 return 0; 13597 }
static int auto_congest | ( | const void * | nothing | ) | [static] |
Scheduled congestion on a call.
Definition at line 2963 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.
02964 { 02965 struct sip_pvt *p = (struct sip_pvt *)nothing; 02966 02967 ast_mutex_lock(&p->lock); 02968 p->initid = -1; 02969 if (p->owner) { 02970 /* XXX fails on possible deadlock */ 02971 if (!ast_channel_trylock(p->owner)) { 02972 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 02973 append_history(p, "Cong", "Auto-congesting (timer)"); 02974 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 02975 ast_channel_unlock(p->owner); 02976 } 02977 } 02978 ast_mutex_unlock(&p->lock); 02979 return 0; 02980 }
static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 4500 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().
04501 { 04502 char buf[33]; 04503 04504 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip)); 04505 04506 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04507 04508 }
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 4511 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().
04512 { 04513 char buf[33]; 04514 04515 const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip)); 04516 04517 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04518 }
static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 7004 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().
07005 { 07006 /* Construct Contact: header */ 07007 if (ourport != STANDARD_SIP_PORT) 07008 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); 07009 else 07010 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip)); 07011 }
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 17260 of file chan_sip.c.
References __set_address_from_contact(), sip_peer::accountcode, add_realm_authentication(), sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_copy_string(), ast_free_ha(), ast_get_group(), ast_get_ip(), ast_get_ip_or_srv(), ast_get_time_t(), ast_inet_ntoa(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), AST_SCHED_DEL, ast_set2_flag, ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), ast_variables_destroy(), ASTOBJ_CONTAINER_FIND_UNLINK_FULL, ASTOBJ_FLAG_MARKED, ASTOBJ_INIT, ASTOBJ_UNMARK, ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, clear_realm_authentication(), sip_peer::contactha, sip_peer::context, sip_peer::defaddr, DEFAULT_MAXMS, destroy_association(), sip_peer::expire, ast_flags::flags, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_contact_ha, global_flags, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, ast_variable::name, sip_peer::name, ast_variable::next, sip_peer::objflags, option_debug, peerl, sip_peer::pickupgroup, sip_peer::prefs, reg_source_db(), sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sched, sip_peer::secret, set_peer_defaults(), sip_destroy_peer(), SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_REALTIME, SIP_USEREQPHONE, STANDARD_SIP_PORT, sip_peer::subscribecontext, sip_peer::tohost, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, sip_peer::username, ast_variable::value, and sip_peer::vmexten.
17261 { 17262 struct sip_peer *peer = NULL; 17263 struct ast_ha *oldha = NULL; 17264 int obproxyfound=0; 17265 int found=0; 17266 int firstpass=1; 17267 int format=0; /* Ama flags */ 17268 time_t regseconds = 0; 17269 char *varname = NULL, *varval = NULL; 17270 struct ast_variable *tmpvar = NULL; 17271 struct ast_flags peerflags[2] = {{(0)}}; 17272 struct ast_flags mask[2] = {{(0)}}; 17273 char fullcontact[sizeof(peer->fullcontact)] = ""; 17274 17275 if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 17276 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 17277 /* We also use a case-sensitive comparison (unlike find_peer) so 17278 that case changes made to the peer name will be properly handled 17279 during reload 17280 */ 17281 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 17282 17283 if (peer) { 17284 /* Already in the list, remove it and it will be added back (or FREE'd) */ 17285 found = 1; 17286 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 17287 firstpass = 0; 17288 } else { 17289 if (!(peer = ast_calloc(1, sizeof(*peer)))) 17290 return NULL; 17291 17292 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 17293 rpeerobjs++; 17294 else 17295 speerobjs++; 17296 ASTOBJ_INIT(peer); 17297 } 17298 /* Note that our peer HAS had its reference count incrased */ 17299 if (firstpass) { 17300 peer->lastmsgssent = -1; 17301 oldha = peer->ha; 17302 peer->ha = NULL; 17303 set_peer_defaults(peer); /* Set peer defaults */ 17304 } 17305 if (!found && name) 17306 ast_copy_string(peer->name, name, sizeof(peer->name)); 17307 17308 /* If we have channel variables, remove them (reload) */ 17309 if (peer->chanvars) { 17310 ast_variables_destroy(peer->chanvars); 17311 peer->chanvars = NULL; 17312 /* XXX should unregister ? */ 17313 } 17314 17315 /* If we have realm authentication information, remove them (reload) */ 17316 clear_realm_authentication(peer->auth); 17317 peer->auth = NULL; 17318 17319 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 17320 if (handle_common_options(&peerflags[0], &mask[0], v)) 17321 continue; 17322 if (realtime && !strcasecmp(v->name, "regseconds")) { 17323 ast_get_time_t(v->value, ®seconds, 0, NULL); 17324 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 17325 inet_aton(v->value, &(peer->addr.sin_addr)); 17326 } else if (realtime && !strcasecmp(v->name, "name")) 17327 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 17328 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 17329 /* Reconstruct field, because realtime separates our value at the ';' */ 17330 if (!ast_strlen_zero(fullcontact)) { 17331 strncat(fullcontact, ";", sizeof(fullcontact) - strlen(fullcontact) - 1); 17332 strncat(fullcontact, v->value, sizeof(fullcontact) - strlen(fullcontact) - 1); 17333 } else { 17334 ast_copy_string(fullcontact, v->value, sizeof(fullcontact)); 17335 ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT); 17336 } 17337 } else if (!strcasecmp(v->name, "secret")) 17338 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 17339 else if (!strcasecmp(v->name, "md5secret")) 17340 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 17341 else if (!strcasecmp(v->name, "auth")) 17342 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 17343 else if (!strcasecmp(v->name, "callerid")) { 17344 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 17345 } else if (!strcasecmp(v->name, "fullname")) { 17346 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 17347 } else if (!strcasecmp(v->name, "cid_number")) { 17348 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 17349 } else if (!strcasecmp(v->name, "context")) { 17350 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 17351 } else if (!strcasecmp(v->name, "subscribecontext")) { 17352 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 17353 } else if (!strcasecmp(v->name, "fromdomain")) { 17354 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 17355 } else if (!strcasecmp(v->name, "usereqphone")) { 17356 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 17357 } else if (!strcasecmp(v->name, "fromuser")) { 17358 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 17359 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 17360 if (!strcasecmp(v->value, "dynamic")) { 17361 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 17362 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 17363 } else { 17364 /* They'll register with us */ 17365 if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 17366 /* Initialize stuff if this is a new peer, or if it used to be 17367 * non-dynamic before the reload. */ 17368 memset(&peer->addr.sin_addr, 0, 4); 17369 if (peer->addr.sin_port) { 17370 /* If we've already got a port, make it the default rather than absolute */ 17371 peer->defaddr.sin_port = peer->addr.sin_port; 17372 peer->addr.sin_port = 0; 17373 } 17374 } 17375 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 17376 } 17377 } else { 17378 /* Non-dynamic. Make sure we become that way if we're not */ 17379 if (!AST_SCHED_DEL(sched, peer->expire)) { 17380 struct sip_peer *peer_ptr = peer; 17381 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 17382 } 17383 ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 17384 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 17385 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 17386 ASTOBJ_UNREF(peer, sip_destroy_peer); 17387 return NULL; 17388 } 17389 } 17390 if (!strcasecmp(v->name, "outboundproxy")) 17391 obproxyfound=1; 17392 else { 17393 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 17394 if (!peer->addr.sin_port) 17395 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 17396 } 17397 if (global_dynamic_exclude_static) { 17398 global_contact_ha = ast_append_ha("deny", (char *)ast_inet_ntoa(peer->addr.sin_addr), global_contact_ha); 17399 } 17400 } 17401 } else if (!strcasecmp(v->name, "defaultip")) { 17402 if (ast_get_ip(&peer->defaddr, v->value)) { 17403 ASTOBJ_UNREF(peer, sip_destroy_peer); 17404 return NULL; 17405 } 17406 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 17407 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 17408 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 17409 peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha); 17410 } else if (!strcasecmp(v->name, "port")) { 17411 if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) 17412 peer->defaddr.sin_port = htons(atoi(v->value)); 17413 else 17414 peer->addr.sin_port = htons(atoi(v->value)); 17415 } else if (!strcasecmp(v->name, "callingpres")) { 17416 peer->callingpres = ast_parse_caller_presentation(v->value); 17417 if (peer->callingpres == -1) 17418 peer->callingpres = atoi(v->value); 17419 } else if (!strcasecmp(v->name, "username")) { 17420 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 17421 } else if (!strcasecmp(v->name, "language")) { 17422 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 17423 } else if (!strcasecmp(v->name, "regexten")) { 17424 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 17425 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 17426 peer->call_limit = atoi(v->value); 17427 if (peer->call_limit < 0) 17428 peer->call_limit = 0; 17429 } else if (!strcasecmp(v->name, "amaflags")) { 17430 format = ast_cdr_amaflags2int(v->value); 17431 if (format < 0) { 17432 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 17433 } else { 17434 peer->amaflags = format; 17435 } 17436 } else if (!strcasecmp(v->name, "accountcode")) { 17437 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 17438 } else if (!strcasecmp(v->name, "mohinterpret") 17439 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17440 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 17441 } else if (!strcasecmp(v->name, "mohsuggest")) { 17442 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 17443 } else if (!strcasecmp(v->name, "mailbox")) { 17444 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 17445 } else if (!strcasecmp(v->name, "hasvoicemail")) { 17446 /* People expect that if 'hasvoicemail' is set, that the mailbox will 17447 * be also set, even if not explicitly specified. */ 17448 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 17449 ast_copy_string(peer->mailbox, name, sizeof(peer->mailbox)); 17450 } 17451 } else if (!strcasecmp(v->name, "subscribemwi")) { 17452 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 17453 } else if (!strcasecmp(v->name, "vmexten")) { 17454 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 17455 } else if (!strcasecmp(v->name, "callgroup")) { 17456 peer->callgroup = ast_get_group(v->value); 17457 } else if (!strcasecmp(v->name, "allowtransfer")) { 17458 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17459 } else if (!strcasecmp(v->name, "pickupgroup")) { 17460 peer->pickupgroup = ast_get_group(v->value); 17461 } else if (!strcasecmp(v->name, "allow")) { 17462 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 17463 } else if (!strcasecmp(v->name, "disallow")) { 17464 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 17465 } else if (!strcasecmp(v->name, "autoframing")) { 17466 peer->autoframing = ast_true(v->value); 17467 } else if (!strcasecmp(v->name, "rtptimeout")) { 17468 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 17469 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17470 peer->rtptimeout = global_rtptimeout; 17471 } 17472 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 17473 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 17474 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17475 peer->rtpholdtimeout = global_rtpholdtimeout; 17476 } 17477 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 17478 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 17479 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 17480 peer->rtpkeepalive = global_rtpkeepalive; 17481 } 17482 } else if (!strcasecmp(v->name, "setvar")) { 17483 /* Set peer channel variable */ 17484 varname = ast_strdupa(v->value); 17485 if ((varval = strchr(varname, '='))) { 17486 *varval++ = '\0'; 17487 if ((tmpvar = ast_variable_new(varname, varval))) { 17488 tmpvar->next = peer->chanvars; 17489 peer->chanvars = tmpvar; 17490 } 17491 } 17492 } else if (!strcasecmp(v->name, "qualify")) { 17493 if (!strcasecmp(v->value, "no")) { 17494 peer->maxms = 0; 17495 } else if (!strcasecmp(v->value, "yes")) { 17496 peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS; 17497 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 17498 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); 17499 peer->maxms = 0; 17500 } 17501 if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) { 17502 /* This would otherwise cause a network storm, where the 17503 * qualify response refreshes the peer from the database, 17504 * which in turn causes another qualify to be sent, ad 17505 * infinitum. */ 17506 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); 17507 peer->maxms = 0; 17508 } 17509 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17510 peer->maxcallbitrate = atoi(v->value); 17511 if (peer->maxcallbitrate < 0) 17512 peer->maxcallbitrate = default_maxcallbitrate; 17513 } 17514 } 17515 if (!ast_strlen_zero(fullcontact)) { 17516 ast_copy_string(peer->fullcontact, fullcontact, sizeof(peer->fullcontact)); 17517 /* We have a hostname in the fullcontact, but if we don't have an 17518 * address listed on the entry (or if it's 'dynamic'), then we need to 17519 * parse the entry to obtain the IP address, so a dynamic host can be 17520 * contacted immediately after reload (as opposed to waiting for it to 17521 * register once again). */ 17522 __set_address_from_contact(fullcontact, &peer->addr); 17523 } 17524 17525 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) { 17526 time_t nowtime = time(NULL); 17527 17528 if ((nowtime - regseconds) > 0) { 17529 destroy_association(peer); 17530 memset(&peer->addr, 0, sizeof(peer->addr)); 17531 if (option_debug) 17532 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 17533 } 17534 } 17535 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 17536 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 17537 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 17538 global_allowsubscribe = TRUE; /* No global ban any more */ 17539 if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME)) 17540 reg_source_db(peer); 17541 ASTOBJ_UNMARK(peer); 17542 ast_free_ha(oldha); 17543 return peer; 17544 }
static int build_reply_digest | ( | struct sip_pvt * | p, | |
int | method, | |||
char * | digest, | |||
int | digest_len | |||
) | [static] |
Build reply digest.
Definition at line 11794 of file chan_sip.c.
References append_history, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_md5_hash(), ast_random(), ast_strlen_zero(), authl, sip_pvt::authname, sip_pvt::callid, sip_pvt::domain, find_realm_authentication(), LOG_DEBUG, sip_auth::md5secret, sip_registry::md5secret, sip_pvt::nonce, sip_pvt::noncecount, sip_pvt::opaque, sip_registry::opaque, sip_pvt::peerauth, sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_pvt::qop, sip_pvt::realm, sip_pvt::sa, sip_auth::secret, secret, sip_methods, sipdebug, text, sip_pvt::uri, sip_auth::username, sip_pvt::username, and username.
Referenced by reply_digest(), transmit_register(), and transmit_request_with_auth().
11795 { 11796 char a1[256]; 11797 char a2[256]; 11798 char a1_hash[256]; 11799 char a2_hash[256]; 11800 char resp[256]; 11801 char resp_hash[256]; 11802 char uri[256]; 11803 char opaque[256] = ""; 11804 char cnonce[80]; 11805 const char *username; 11806 const char *secret; 11807 const char *md5secret; 11808 struct sip_auth *auth = NULL; /* Realm authentication */ 11809 11810 if (!ast_strlen_zero(p->domain)) 11811 ast_copy_string(uri, p->domain, sizeof(uri)); 11812 else if (!ast_strlen_zero(p->uri)) 11813 ast_copy_string(uri, p->uri, sizeof(uri)); 11814 else 11815 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr)); 11816 11817 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 11818 11819 /* Check if we have separate auth credentials */ 11820 if(!(auth = find_realm_authentication(p->peerauth, p->realm))) /* Start with peer list */ 11821 auth = find_realm_authentication(authl, p->realm); /* If not, global list */ 11822 11823 if (auth) { 11824 ast_log(LOG_DEBUG, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username); 11825 username = auth->username; 11826 secret = auth->secret; 11827 md5secret = auth->md5secret; 11828 if (sipdebug) 11829 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 11830 } else { 11831 /* No authentication, use peer or register= config */ 11832 username = p->authname; 11833 secret = p->peersecret; 11834 md5secret = p->peermd5secret; 11835 } 11836 if (ast_strlen_zero(username)) /* We have no authentication */ 11837 return -1; 11838 11839 /* Calculate SIP digest response */ 11840 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 11841 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 11842 if (!ast_strlen_zero(md5secret)) 11843 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 11844 else 11845 ast_md5_hash(a1_hash,a1); 11846 ast_md5_hash(a2_hash,a2); 11847 11848 p->noncecount++; 11849 if (!ast_strlen_zero(p->qop)) 11850 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 11851 else 11852 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 11853 ast_md5_hash(resp_hash, resp); 11854 11855 /* only include the opaque string if it's set */ 11856 if (!ast_strlen_zero(p->opaque)) { 11857 snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque); 11858 } 11859 11860 /* XXX We hard code our qop to "auth" for now. XXX */ 11861 if (!ast_strlen_zero(p->qop)) 11862 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); 11863 else 11864 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); 11865 11866 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 11867 11868 return 0; 11869 }
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 8463 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().
08464 { 08465 struct sip_route *thishop, *head, *tail; 08466 int start = 0; 08467 int len; 08468 const char *rr, *contact, *c; 08469 08470 /* Once a persistant route is set, don't fool with it */ 08471 if (p->route && p->route_persistant) { 08472 if (option_debug) 08473 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 08474 return; 08475 } 08476 08477 if (p->route) { 08478 free_old_route(p->route); 08479 p->route = NULL; 08480 } 08481 08482 /* We only want to create the route set the first time this is called */ 08483 p->route_persistant = 1; 08484 08485 /* Build a tailq, then assign it to p->route when done. 08486 * If backwards, we add entries from the head so they end up 08487 * in reverse order. However, we do need to maintain a correct 08488 * tail pointer because the contact is always at the end. 08489 */ 08490 head = NULL; 08491 tail = head; 08492 /* 1st we pass through all the hops in any Record-Route headers */ 08493 for (;;) { 08494 /* Each Record-Route header */ 08495 rr = __get_header(req, "Record-Route", &start); 08496 if (*rr == '\0') 08497 break; 08498 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 08499 ++rr; 08500 len = strcspn(rr, ">") + 1; 08501 /* Make a struct route */ 08502 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08503 /* ast_calloc is not needed because all fields are initialized in this block */ 08504 ast_copy_string(thishop->hop, rr, len); 08505 if (option_debug > 1) 08506 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 08507 /* Link in */ 08508 if (backwards) { 08509 /* Link in at head so they end up in reverse order */ 08510 thishop->next = head; 08511 head = thishop; 08512 /* If this was the first then it'll be the tail */ 08513 if (!tail) 08514 tail = thishop; 08515 } else { 08516 thishop->next = NULL; 08517 /* Link in at the end */ 08518 if (tail) 08519 tail->next = thishop; 08520 else 08521 head = thishop; 08522 tail = thishop; 08523 } 08524 } 08525 } 08526 } 08527 08528 /* Only append the contact if we are dealing with a strict router */ 08529 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 08530 /* 2nd append the Contact: if there is one */ 08531 /* Can be multiple Contact headers, comma separated values - we just take the first */ 08532 contact = get_header(req, "Contact"); 08533 if (!ast_strlen_zero(contact)) { 08534 if (option_debug > 1) 08535 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 08536 /* Look for <: delimited address */ 08537 c = strchr(contact, '<'); 08538 if (c) { 08539 /* Take to > */ 08540 ++c; 08541 len = strcspn(c, ">") + 1; 08542 } else { 08543 /* No <> - just take the lot */ 08544 c = contact; 08545 len = strlen(contact) + 1; 08546 } 08547 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08548 /* ast_calloc is not needed because all fields are initialized in this block */ 08549 ast_copy_string(thishop->hop, c, len); 08550 thishop->next = NULL; 08551 /* Goes at the end */ 08552 if (tail) 08553 tail->next = thishop; 08554 else 08555 head = thishop; 08556 } 08557 } 08558 } 08559 08560 /* Store as new route */ 08561 p->route = head; 08562 08563 /* For debugging dump what we ended up with */ 08564 if (sip_debug_test_pvt(p)) 08565 list_route(p->route); 08566 }
static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 7014 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().
07015 { 07016 int send_pres_tags = TRUE; 07017 const char *privacy=NULL; 07018 const char *screen=NULL; 07019 char buf[256]; 07020 const char *clid = default_callerid; 07021 const char *clin = NULL; 07022 const char *fromdomain; 07023 07024 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 07025 return; 07026 07027 if (p->owner && p->owner->cid.cid_num) 07028 clid = p->owner->cid.cid_num; 07029 if (p->owner && p->owner->cid.cid_name) 07030 clin = p->owner->cid.cid_name; 07031 if (ast_strlen_zero(clin)) 07032 clin = clid; 07033 07034 switch (p->callingpres) { 07035 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 07036 privacy = "off"; 07037 screen = "no"; 07038 break; 07039 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 07040 privacy = "off"; 07041 screen = "yes"; 07042 break; 07043 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 07044 privacy = "off"; 07045 screen = "no"; 07046 break; 07047 case AST_PRES_ALLOWED_NETWORK_NUMBER: 07048 privacy = "off"; 07049 screen = "yes"; 07050 break; 07051 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 07052 privacy = "full"; 07053 screen = "no"; 07054 break; 07055 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 07056 privacy = "full"; 07057 screen = "yes"; 07058 break; 07059 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 07060 privacy = "full"; 07061 screen = "no"; 07062 break; 07063 case AST_PRES_PROHIB_NETWORK_NUMBER: 07064 privacy = "full"; 07065 screen = "yes"; 07066 break; 07067 case AST_PRES_NUMBER_NOT_AVAILABLE: 07068 send_pres_tags = FALSE; 07069 break; 07070 default: 07071 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 07072 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 07073 privacy = "full"; 07074 else 07075 privacy = "off"; 07076 screen = "no"; 07077 break; 07078 } 07079 07080 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 07081 07082 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 07083 if (send_pres_tags) 07084 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 07085 ast_string_field_set(p, rpid, buf); 07086 07087 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 07088 S_OR(p->fromuser, clid), 07089 fromdomain, p->tag); 07090 }
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 17080 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.
17081 { 17082 struct sip_user *user; 17083 int format; 17084 struct ast_ha *oldha = NULL; 17085 char *varname = NULL, *varval = NULL; 17086 struct ast_variable *tmpvar = NULL; 17087 struct ast_flags userflags[2] = {{(0)}}; 17088 struct ast_flags mask[2] = {{(0)}}; 17089 17090 17091 if (!(user = ast_calloc(1, sizeof(*user)))) 17092 return NULL; 17093 17094 suserobjs++; 17095 ASTOBJ_INIT(user); 17096 ast_copy_string(user->name, name, sizeof(user->name)); 17097 oldha = user->ha; 17098 user->ha = NULL; 17099 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 17100 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 17101 user->capability = global_capability; 17102 user->allowtransfer = global_allowtransfer; 17103 user->maxcallbitrate = default_maxcallbitrate; 17104 user->autoframing = global_autoframing; 17105 user->prefs = default_prefs; 17106 /* set default context */ 17107 strcpy(user->context, default_context); 17108 strcpy(user->language, default_language); 17109 strcpy(user->mohinterpret, default_mohinterpret); 17110 strcpy(user->mohsuggest, default_mohsuggest); 17111 /* First we walk through the v parameters list and then the alt parameters list */ 17112 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 17113 if (handle_common_options(&userflags[0], &mask[0], v)) 17114 continue; 17115 17116 if (!strcasecmp(v->name, "context")) { 17117 ast_copy_string(user->context, v->value, sizeof(user->context)); 17118 } else if (!strcasecmp(v->name, "subscribecontext")) { 17119 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 17120 } else if (!strcasecmp(v->name, "setvar")) { 17121 varname = ast_strdupa(v->value); 17122 if ((varval = strchr(varname,'='))) { 17123 *varval++ = '\0'; 17124 if ((tmpvar = ast_variable_new(varname, varval))) { 17125 tmpvar->next = user->chanvars; 17126 user->chanvars = tmpvar; 17127 } 17128 } 17129 } else if (!strcasecmp(v->name, "permit") || 17130 !strcasecmp(v->name, "deny")) { 17131 user->ha = ast_append_ha(v->name, v->value, user->ha); 17132 } else if (!strcasecmp(v->name, "allowtransfer")) { 17133 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17134 } else if (!strcasecmp(v->name, "secret")) { 17135 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 17136 } else if (!strcasecmp(v->name, "md5secret")) { 17137 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 17138 } else if (!strcasecmp(v->name, "callerid")) { 17139 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 17140 } else if (!strcasecmp(v->name, "fullname")) { 17141 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 17142 } else if (!strcasecmp(v->name, "cid_number")) { 17143 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 17144 } else if (!strcasecmp(v->name, "callgroup")) { 17145 user->callgroup = ast_get_group(v->value); 17146 } else if (!strcasecmp(v->name, "pickupgroup")) { 17147 user->pickupgroup = ast_get_group(v->value); 17148 } else if (!strcasecmp(v->name, "language")) { 17149 ast_copy_string(user->language, v->value, sizeof(user->language)); 17150 } else if (!strcasecmp(v->name, "mohinterpret") 17151 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17152 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 17153 } else if (!strcasecmp(v->name, "mohsuggest")) { 17154 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 17155 } else if (!strcasecmp(v->name, "accountcode")) { 17156 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 17157 } else if (!strcasecmp(v->name, "call-limit")) { 17158 user->call_limit = atoi(v->value); 17159 if (user->call_limit < 0) 17160 user->call_limit = 0; 17161 } else if (!strcasecmp(v->name, "amaflags")) { 17162 format = ast_cdr_amaflags2int(v->value); 17163 if (format < 0) { 17164 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 17165 } else { 17166 user->amaflags = format; 17167 } 17168 } else if (!strcasecmp(v->name, "allow")) { 17169 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 17170 } else if (!strcasecmp(v->name, "disallow")) { 17171 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 17172 } else if (!strcasecmp(v->name, "autoframing")) { 17173 user->autoframing = ast_true(v->value); 17174 } else if (!strcasecmp(v->name, "callingpres")) { 17175 user->callingpres = ast_parse_caller_presentation(v->value); 17176 if (user->callingpres == -1) 17177 user->callingpres = atoi(v->value); 17178 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17179 user->maxcallbitrate = atoi(v->value); 17180 if (user->maxcallbitrate < 0) 17181 user->maxcallbitrate = default_maxcallbitrate; 17182 } 17183 /* We can't just report unknown options here because this may be a 17184 * type=friend entry. All user options are valid for a peer, but not 17185 * the other way around. */ 17186 } 17187 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 17188 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 17189 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 17190 global_allowsubscribe = TRUE; /* No global ban any more */ 17191 ast_free_ha(oldha); 17192 return user; 17193 }
static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 1810 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, ast_test_flag, sip_pvt::branch, sip_pvt::flags, sip_pvt::ourip, ourport, SIP_NAT, and SIP_NAT_RFC3581.
Referenced by reqprep(), sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_invite(), transmit_register(), and transmit_response_using_temp().
01811 { 01812 /* Work around buggy UNIDEN UIP200 firmware */ 01813 const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : ""; 01814 01815 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01816 ast_string_field_build(p, via, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s", 01817 ast_inet_ntoa(p->ourip), ourport, (int) p->branch, rport); 01818 }
static int cb_extensionstate | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 8771 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().
08772 { 08773 struct sip_pvt *p = data; 08774 08775 ast_mutex_lock(&p->lock); 08776 08777 switch(state) { 08778 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 08779 case AST_EXTENSION_REMOVED: /* Extension is gone */ 08780 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 08781 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08782 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 08783 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); 08784 p->stateid = -1; 08785 p->subscribed = NONE; 08786 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 08787 break; 08788 default: /* Tell user */ 08789 p->laststate = state; 08790 break; 08791 } 08792 if (p->subscribed != NONE) { /* Only send state NOTIFY if we know the format */ 08793 if (!p->pendinginvite) { 08794 transmit_state_notify(p, state, 1, FALSE); 08795 } else { 08796 /* We already have a NOTIFY sent that is not answered. Queue the state up. 08797 if many state changes happen meanwhile, we will only send a notification of the last one */ 08798 ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 08799 } 08800 } 08801 if (option_verbose > 1) 08802 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, 08803 ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : ""); 08804 08805 08806 ast_mutex_unlock(&p->lock); 08807 08808 return 0; 08809 }
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 5084 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().
05085 { 05086 if (global_notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) 05087 sip_peer_hold(dialog, holdstate); 05088 if (global_callevents) 05089 manager_event(EVENT_FLAG_CALL, holdstate ? "Hold" : "Unhold", 05090 "Channel: %s\r\n" 05091 "Uniqueid: %s\r\n", 05092 dialog->owner->name, 05093 dialog->owner->uniqueid); 05094 append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data); 05095 if (!holdstate) { /* Put off remote hold */ 05096 ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 05097 return; 05098 } 05099 /* No address for RTP, we're on hold */ 05100 05101 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 05102 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 05103 else if (sendonly == 2) /* Inactive stream */ 05104 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 05105 else 05106 ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE); 05107 return; 05108 }
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 8576 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().
08579 { 08580 const char *response = "407 Proxy Authentication Required"; 08581 const char *reqheader = "Proxy-Authorization"; 08582 const char *respheader = "Proxy-Authenticate"; 08583 const char *authtoken; 08584 char a1_hash[256]; 08585 char resp_hash[256]=""; 08586 char *c; 08587 int wrongnonce = FALSE; 08588 int good_response; 08589 const char *usednonce = p->randdata; 08590 struct ast_dynamic_str *buf; 08591 int res; 08592 08593 /* table of recognised keywords, and their value in the digest */ 08594 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 08595 struct x { 08596 const char *key; 08597 const char *s; 08598 } *i, keys[] = { 08599 [K_RESP] = { "response=", "" }, 08600 [K_URI] = { "uri=", "" }, 08601 [K_USER] = { "username=", "" }, 08602 [K_NONCE] = { "nonce=", "" }, 08603 [K_LAST] = { NULL, NULL} 08604 }; 08605 08606 /* Always OK if no secret */ 08607 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 08608 return AUTH_SUCCESSFUL; 08609 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 08610 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 08611 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 08612 different circumstances! What a surprise. */ 08613 response = "401 Unauthorized"; 08614 reqheader = "Authorization"; 08615 respheader = "WWW-Authenticate"; 08616 } 08617 authtoken = get_header(req, reqheader); 08618 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 08619 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 08620 information */ 08621 if (!reliable) { 08622 /* Resend message if this was NOT a reliable delivery. Otherwise the 08623 retransmission should get it */ 08624 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08625 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 08626 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08627 } 08628 return AUTH_CHALLENGE_SENT; 08629 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 08630 /* We have no auth, so issue challenge and request authentication */ 08631 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08632 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08633 /* Schedule auto destroy in 32 seconds */ 08634 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08635 return AUTH_CHALLENGE_SENT; 08636 } 08637 08638 /* --- We have auth, so check it */ 08639 08640 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 08641 an example in the spec of just what it is you're doing a hash on. */ 08642 08643 if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) 08644 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08645 08646 /* Make a copy of the response and parse it */ 08647 res = ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken); 08648 08649 if (res == AST_DYNSTR_BUILD_FAILED) 08650 return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */ 08651 08652 c = buf->str; 08653 08654 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 08655 for (i = keys; i->key != NULL; i++) { 08656 const char *separator = ","; /* default */ 08657 08658 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 08659 continue; 08660 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08661 c += strlen(i->key); 08662 if (*c == '"') { /* in quotes. Skip first and look for last */ 08663 c++; 08664 separator = "\""; 08665 } 08666 i->s = c; 08667 strsep(&c, separator); 08668 break; 08669 } 08670 if (i->key == NULL) /* not found, jump after space or comma */ 08671 strsep(&c, " ,"); 08672 } 08673 08674 /* Verify that digest username matches the username we auth as */ 08675 if (strcmp(username, keys[K_USER].s)) { 08676 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 08677 username, keys[K_USER].s); 08678 /* Oops, we're trying something here */ 08679 return AUTH_USERNAME_MISMATCH; 08680 } 08681 08682 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 08683 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */ 08684 wrongnonce = TRUE; 08685 usednonce = keys[K_NONCE].s; 08686 } 08687 08688 if (!ast_strlen_zero(md5secret)) 08689 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 08690 else { 08691 char a1[256]; 08692 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 08693 ast_md5_hash(a1_hash, a1); 08694 } 08695 08696 /* compute the expected response to compare with what we received */ 08697 { 08698 char a2[256]; 08699 char a2_hash[256]; 08700 char resp[256]; 08701 08702 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 08703 S_OR(keys[K_URI].s, uri)); 08704 ast_md5_hash(a2_hash, a2); 08705 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 08706 ast_md5_hash(resp_hash, resp); 08707 } 08708 08709 good_response = keys[K_RESP].s && 08710 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 08711 if (wrongnonce) { 08712 if (good_response) { 08713 if (sipdebug) 08714 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To")); 08715 /* We got working auth token, based on stale nonce . */ 08716 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08717 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 08718 } else { 08719 /* Everything was wrong, so give the device one more try with a new challenge */ 08720 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 08721 if (sipdebug) 08722 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 08723 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08724 } else { 08725 if (sipdebug) 08726 ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To")); 08727 } 08728 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 08729 } 08730 08731 /* Schedule auto destroy in 32 seconds */ 08732 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08733 return AUTH_CHALLENGE_SENT; 08734 } 08735 if (good_response) { 08736 append_history(p, "AuthOK", "Auth challenge succesful for %s", username); 08737 return AUTH_SUCCESSFUL; 08738 } 08739 08740 /* Ok, we have a bad username/secret pair */ 08741 /* Tell the UAS not to re-send this authentication data, because 08742 it will continue to fail 08743 */ 08744 08745 return AUTH_SECRET_FAILED; 08746 }
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 12268 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().
12269 { 12270 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 12271 /* if we can't BYE, then this is really a pending CANCEL */ 12272 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) 12273 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 12274 /* Actually don't destroy us yet, wait for the 487 on our original 12275 INVITE, but do set an autodestruct just in case we never get it. */ 12276 else { 12277 /* We have a pending outbound invite, don't send someting 12278 new in-transaction */ 12279 if (p->pendinginvite) 12280 return; 12281 12282 /* Perhaps there is an SD change INVITE outstanding */ 12283 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 12284 } 12285 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 12286 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12287 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 12288 /* if we can't REINVITE, hold it for later */ 12289 if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) { 12290 if (option_debug) 12291 ast_log(LOG_DEBUG, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid); 12292 } else { 12293 if (option_debug) 12294 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 12295 /* Didn't get to reinvite yet, so do it now */ 12296 transmit_reinvite_with_sdp(p); 12297 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 12298 } 12299 } 12300 }
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 16959 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().
16960 { 16961 struct domain *d; 16962 int result = 0; 16963 16964 AST_LIST_LOCK(&domain_list); 16965 AST_LIST_TRAVERSE(&domain_list, d, list) { 16966 if (strcasecmp(d->domain, domain)) 16967 continue; 16968 16969 if (len && !ast_strlen_zero(d->context)) 16970 ast_copy_string(context, d->context, len); 16971 16972 result = 1; 16973 break; 16974 } 16975 AST_LIST_UNLOCK(&domain_list); 16976 16977 return result; 16978 }
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 9889 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
09890 { 09891 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 09892 }
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 9565 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().
09568 { 09569 struct sip_user *user = NULL; 09570 struct sip_peer *peer; 09571 char from[256], *c; 09572 char *of; 09573 char rpid_num[50]; 09574 const char *rpid; 09575 enum check_auth_result res = AUTH_SUCCESSFUL; 09576 char *t; 09577 char calleridname[50]; 09578 int debug=sip_debug_test_addr(sin); 09579 struct ast_variable *tmpvar = NULL, *v = NULL; 09580 char *uri2 = ast_strdupa(uri); 09581 09582 /* Terminate URI */ 09583 t = uri2; 09584 while (*t && *t > 32 && *t != ';') 09585 t++; 09586 *t = '\0'; 09587 ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */ 09588 if (pedanticsipchecking) 09589 ast_uri_decode(from); 09590 /* XXX here tries to map the username for invite things */ 09591 memset(calleridname, 0, sizeof(calleridname)); 09592 get_calleridname(from, calleridname, sizeof(calleridname)); 09593 if (calleridname[0]) 09594 ast_string_field_set(p, cid_name, calleridname); 09595 09596 rpid = get_header(req, "Remote-Party-ID"); 09597 memset(rpid_num, 0, sizeof(rpid_num)); 09598 if (!ast_strlen_zero(rpid)) 09599 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 09600 09601 of = get_in_brackets(from); 09602 if (ast_strlen_zero(p->exten)) { 09603 t = uri2; 09604 if (!strncasecmp(t, "sip:", 4)) 09605 t+= 4; 09606 ast_string_field_set(p, exten, t); 09607 t = strchr(p->exten, '@'); 09608 if (t) 09609 *t = '\0'; 09610 if (ast_strlen_zero(p->our_contact)) 09611 build_contact(p); 09612 } 09613 /* save the URI part of the From header */ 09614 ast_string_field_set(p, from, of); 09615 if (strncasecmp(of, "sip:", 4)) { 09616 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 09617 } else 09618 of += 4; 09619 /* Get just the username part */ 09620 if ((c = strchr(of, '@'))) { 09621 char *tmp; 09622 *c = '\0'; 09623 if ((c = strchr(of, ':'))) 09624 *c = '\0'; 09625 tmp = ast_strdupa(of); 09626 /* We need to be able to handle auth-headers looking like 09627 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 09628 */ 09629 tmp = strsep(&tmp, ";"); 09630 if (ast_is_shrinkable_phonenumber(tmp)) 09631 ast_shrink_phone_number(tmp); 09632 ast_string_field_set(p, cid_num, tmp); 09633 } 09634 09635 if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */ 09636 user = find_user(of, 1); 09637 09638 /* Find user based on user name in the from header */ 09639 if (user && ast_apply_ha(user->ha, sin)) { 09640 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09641 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09642 if (sipmethod == SIP_INVITE) { 09643 /* copy channel vars */ 09644 for (v = user->chanvars ; v ; v = v->next) { 09645 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09646 tmpvar->next = p->chanvars; 09647 p->chanvars = tmpvar; 09648 } 09649 } 09650 } 09651 p->prefs = user->prefs; 09652 /* Set Frame packetization */ 09653 if (p->rtp) { 09654 ast_rtp_codec_setpref(p->rtp, &p->prefs); 09655 p->autoframing = user->autoframing; 09656 } 09657 /* replace callerid if rpid found, and not restricted */ 09658 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09659 char *tmp; 09660 if (*calleridname) 09661 ast_string_field_set(p, cid_name, calleridname); 09662 tmp = ast_strdupa(rpid_num); 09663 if (ast_is_shrinkable_phonenumber(tmp)) 09664 ast_shrink_phone_number(tmp); 09665 ast_string_field_set(p, cid_num, tmp); 09666 } 09667 09668 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 09669 09670 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09671 if (sip_cancel_destroy(p)) 09672 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 09673 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09674 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09675 /* Copy SIP extensions profile from INVITE */ 09676 if (p->sipoptions) 09677 user->sipoptions = p->sipoptions; 09678 09679 /* If we have a call limit, set flag */ 09680 if (user->call_limit) 09681 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09682 if (!ast_strlen_zero(user->context)) 09683 ast_string_field_set(p, context, user->context); 09684 if (!ast_strlen_zero(user->cid_num)) { 09685 char *tmp = ast_strdupa(user->cid_num); 09686 if (ast_is_shrinkable_phonenumber(tmp)) 09687 ast_shrink_phone_number(tmp); 09688 ast_string_field_set(p, cid_num, tmp); 09689 } 09690 if (!ast_strlen_zero(user->cid_name)) 09691 ast_string_field_set(p, cid_name, user->cid_name); 09692 ast_string_field_set(p, username, user->name); 09693 ast_string_field_set(p, peername, user->name); 09694 ast_string_field_set(p, peersecret, user->secret); 09695 ast_string_field_set(p, peermd5secret, user->md5secret); 09696 ast_string_field_set(p, subscribecontext, user->subscribecontext); 09697 ast_string_field_set(p, accountcode, user->accountcode); 09698 ast_string_field_set(p, language, user->language); 09699 ast_string_field_set(p, mohsuggest, user->mohsuggest); 09700 ast_string_field_set(p, mohinterpret, user->mohinterpret); 09701 p->allowtransfer = user->allowtransfer; 09702 p->amaflags = user->amaflags; 09703 p->callgroup = user->callgroup; 09704 p->pickupgroup = user->pickupgroup; 09705 if (user->callingpres) /* User callingpres setting will override RPID header */ 09706 p->callingpres = user->callingpres; 09707 09708 /* Set default codec settings for this call */ 09709 p->capability = user->capability; /* User codec choice */ 09710 p->jointcapability = user->capability; /* Our codecs */ 09711 if (p->peercapability) /* AND with peer's codecs */ 09712 p->jointcapability &= p->peercapability; 09713 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09714 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09715 p->noncodeccapability |= AST_RTP_DTMF; 09716 else 09717 p->noncodeccapability &= ~AST_RTP_DTMF; 09718 p->jointnoncodeccapability = p->noncodeccapability; 09719 if (p->t38.peercapability) 09720 p->t38.jointcapability &= p->t38.peercapability; 09721 p->maxcallbitrate = user->maxcallbitrate; 09722 /* If we do not support video, remove video from call structure */ 09723 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09724 ast_rtp_destroy(p->vrtp); 09725 p->vrtp = NULL; 09726 } 09727 } 09728 if (user && debug) 09729 ast_verbose("Found user '%s'\n", user->name); 09730 } else { 09731 if (user) { 09732 if (!authpeer && debug) 09733 ast_verbose("Found user '%s', but fails host access\n", user->name); 09734 ASTOBJ_UNREF(user,sip_destroy_user); 09735 } 09736 user = NULL; 09737 } 09738 09739 if (!user) { 09740 /* If we didn't find a user match, check for peers */ 09741 if (sipmethod == SIP_SUBSCRIBE) 09742 /* For subscribes, match on peer name only */ 09743 peer = find_peer(of, NULL, 1, 0); 09744 else 09745 /* Look for peer based on the IP address we received data from */ 09746 /* If peer is registered from this IP address or have this as a default 09747 IP address, this call is from the peer 09748 */ 09749 peer = find_peer(NULL, &p->recv, 1, 0); 09750 09751 if (peer) { 09752 /* Set Frame packetization */ 09753 if (p->rtp) { 09754 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09755 p->autoframing = peer->autoframing; 09756 } 09757 if (debug) 09758 ast_verbose("Found peer '%s'\n", peer->name); 09759 09760 /* Take the peer */ 09761 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09762 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09763 09764 /* Copy SIP extensions profile to peer */ 09765 if (p->sipoptions) 09766 peer->sipoptions = p->sipoptions; 09767 09768 /* replace callerid if rpid found, and not restricted */ 09769 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09770 char *tmp = ast_strdupa(rpid_num); 09771 if (*calleridname) 09772 ast_string_field_set(p, cid_name, calleridname); 09773 if (ast_is_shrinkable_phonenumber(tmp)) 09774 ast_shrink_phone_number(tmp); 09775 ast_string_field_set(p, cid_num, tmp); 09776 } 09777 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 09778 09779 ast_string_field_set(p, peersecret, peer->secret); 09780 ast_string_field_set(p, peermd5secret, peer->md5secret); 09781 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 09782 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 09783 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 09784 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 09785 p->callingpres = peer->callingpres; 09786 if (peer->maxms && peer->lastms) 09787 p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 09788 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 09789 /* Pretend there is no required authentication */ 09790 ast_string_field_free(p, peersecret); 09791 ast_string_field_free(p, peermd5secret); 09792 } 09793 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09794 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09795 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09796 /* If we have a call limit, set flag */ 09797 if (peer->call_limit) 09798 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09799 ast_string_field_set(p, peername, peer->name); 09800 ast_string_field_set(p, authname, peer->name); 09801 09802 if (sipmethod == SIP_INVITE) { 09803 /* copy channel vars */ 09804 for (v = peer->chanvars ; v ; v = v->next) { 09805 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09806 tmpvar->next = p->chanvars; 09807 p->chanvars = tmpvar; 09808 } 09809 } 09810 } 09811 if (authpeer) { 09812 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 09813 } 09814 09815 if (!ast_strlen_zero(peer->username)) { 09816 ast_string_field_set(p, username, peer->username); 09817 /* Use the default username for authentication on outbound calls */ 09818 /* XXX this takes the name from the caller... can we override ? */ 09819 ast_string_field_set(p, authname, peer->username); 09820 } 09821 if (!ast_strlen_zero(peer->cid_num)) { 09822 char *tmp = ast_strdupa(peer->cid_num); 09823 if (ast_is_shrinkable_phonenumber(tmp)) 09824 ast_shrink_phone_number(tmp); 09825 ast_string_field_set(p, cid_num, tmp); 09826 } 09827 if (!ast_strlen_zero(peer->cid_name)) 09828 ast_string_field_set(p, cid_name, peer->cid_name); 09829 ast_string_field_set(p, fullcontact, peer->fullcontact); 09830 if (!ast_strlen_zero(peer->context)) 09831 ast_string_field_set(p, context, peer->context); 09832 ast_string_field_set(p, peersecret, peer->secret); 09833 ast_string_field_set(p, peermd5secret, peer->md5secret); 09834 ast_string_field_set(p, language, peer->language); 09835 ast_string_field_set(p, accountcode, peer->accountcode); 09836 p->amaflags = peer->amaflags; 09837 p->callgroup = peer->callgroup; 09838 p->pickupgroup = peer->pickupgroup; 09839 p->capability = peer->capability; 09840 p->prefs = peer->prefs; 09841 p->jointcapability = peer->capability; 09842 if (p->peercapability) 09843 p->jointcapability &= p->peercapability; 09844 p->maxcallbitrate = peer->maxcallbitrate; 09845 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09846 ast_rtp_destroy(p->vrtp); 09847 p->vrtp = NULL; 09848 } 09849 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09850 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09851 p->noncodeccapability |= AST_RTP_DTMF; 09852 else 09853 p->noncodeccapability &= ~AST_RTP_DTMF; 09854 p->jointnoncodeccapability = p->noncodeccapability; 09855 if (p->t38.peercapability) 09856 p->t38.jointcapability &= p->t38.peercapability; 09857 } 09858 ASTOBJ_UNREF(peer, sip_destroy_peer); 09859 } else { 09860 if (debug) 09861 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 09862 09863 /* do we allow guests? */ 09864 if (!global_allowguest) { 09865 if (global_alwaysauthreject) 09866 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 09867 else 09868 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 09869 } else if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09870 char *tmp = ast_strdupa(rpid_num); 09871 if (*calleridname) 09872 ast_string_field_set(p, cid_name, calleridname); 09873 if (ast_is_shrinkable_phonenumber(tmp)) 09874 ast_shrink_phone_number(tmp); 09875 ast_string_field_set(p, cid_num, tmp); 09876 } 09877 } 09878 09879 } 09880 09881 if (user) 09882 ASTOBJ_UNREF(user, sip_destroy_user); 09883 return res; 09884 }
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 9433 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().
09434 { 09435 char via[512]; 09436 char *c, *pt; 09437 struct hostent *hp; 09438 struct ast_hostent ahp; 09439 09440 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 09441 09442 /* Work on the leftmost value of the topmost Via header */ 09443 c = strchr(via, ','); 09444 if (c) 09445 *c = '\0'; 09446 09447 /* Check for rport */ 09448 c = strstr(via, ";rport"); 09449 if (c && (c[6] != '=')) /* rport query, not answer */ 09450 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 09451 09452 c = strchr(via, ';'); 09453 if (c) 09454 *c = '\0'; 09455 09456 c = strchr(via, ' '); 09457 if (c) { 09458 *c = '\0'; 09459 c = ast_skip_blanks(c+1); 09460 if (strcasecmp(via, "SIP/2.0/UDP")) { 09461 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 09462 return; 09463 } 09464 pt = strchr(c, ':'); 09465 if (pt) 09466 *pt++ = '\0'; /* remember port pointer */ 09467 hp = ast_gethostbyname(c, &ahp); 09468 if (!hp) { 09469 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 09470 return; 09471 } 09472 memset(&p->sa, 0, sizeof(p->sa)); 09473 p->sa.sin_family = AF_INET; 09474 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 09475 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 09476 09477 if (sip_debug_test_pvt(p)) { 09478 const struct sockaddr_in *dst = sip_real_dst(p); 09479 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 09480 } 09481 } 09482 }
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 10333 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), ast_copy_string(), and AST_MAX_CONTEXT.
10334 { 10335 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 10336 10337 while ((oldcontext = strsep(&old, "&"))) { 10338 stalecontext = '\0'; 10339 ast_copy_string(newlist, new, sizeof(newlist)); 10340 stringp = newlist; 10341 while ((newcontext = strsep(&stringp, "&"))) { 10342 if (strcmp(newcontext, oldcontext) == 0) { 10343 /* This is not the context you're looking for */ 10344 stalecontext = '\0'; 10345 break; 10346 } else if (strcmp(newcontext, oldcontext)) { 10347 stalecontext = oldcontext; 10348 } 10349 10350 } 10351 if (stalecontext) 10352 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 10353 } 10354 }
static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 17052 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().
17053 { 17054 struct sip_auth *a = authlist; 17055 struct sip_auth *b; 17056 17057 while (a) { 17058 b = a; 17059 a = a->next; 17060 free(b); 17061 } 17062 17063 return 1; 17064 }
static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 16981 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().
16982 { 16983 struct domain *d; 16984 16985 AST_LIST_LOCK(&domain_list); 16986 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 16987 free(d); 16988 AST_LIST_UNLOCK(&domain_list); 16989 }
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 11147 of file chan_sip.c.
References complete_sip_peer().
11148 { 11149 if (pos == 3) 11150 return complete_sip_peer(word, state, 0); 11151 11152 return NULL; 11153 }
static char * complete_sip_peer | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on peer name.
Definition at line 11121 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().
11122 { 11123 char *result = NULL; 11124 int wordlen = strlen(word); 11125 int which = 0; 11126 11127 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 11128 /* locking of the object is not required because only the name and flags are being compared */ 11129 if (!strncasecmp(word, iterator->name, wordlen) && 11130 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 11131 ++which > state) 11132 result = ast_strdup(iterator->name); 11133 } while(0) ); 11134 return result; 11135 }
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 11215 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
11216 { 11217 if (pos == 4) 11218 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11219 return NULL; 11220 }
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 11223 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
11224 { 11225 if (pos == 4) 11226 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 11227 11228 return NULL; 11229 }
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 11138 of file chan_sip.c.
References complete_sip_peer().
11139 { 11140 if (pos == 3) 11141 return complete_sip_peer(word, state, 0); 11142 11143 return NULL; 11144 }
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 11176 of file chan_sip.c.
References complete_sip_user().
11177 { 11178 if (pos == 3) 11179 return complete_sip_user(word, state, 0); 11180 11181 return NULL; 11182 }
static char * complete_sip_user | ( | const char * | word, | |
int | state, | |||
int | flags2 | |||
) | [static] |
Do completion on user name.
Definition at line 11156 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().
11157 { 11158 char *result = NULL; 11159 int wordlen = strlen(word); 11160 int which = 0; 11161 11162 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 11163 /* locking of the object is not required because only the name and flags are being compared */ 11164 if (!strncasecmp(word, iterator->name, wordlen)) { 11165 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 11166 continue; 11167 if (++which > state) { 11168 result = ast_strdup(iterator->name); 11169 } 11170 } 11171 } while(0) ); 11172 return result; 11173 }
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 11098 of file chan_sip.c.
References ast_mutex_lock(), ast_strdup, sip_pvt::callid, iflist, iflock, and sip_pvt::next.
11099 { 11100 int which=0; 11101 struct sip_pvt *cur; 11102 char *c = NULL; 11103 int wordlen = strlen(word); 11104 11105 if (pos != 3) { 11106 return NULL; 11107 } 11108 11109 ast_mutex_lock(&iflock); 11110 for (cur = iflist; cur; cur = cur->next) { 11111 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 11112 c = ast_strdup(cur->callid); 11113 break; 11114 } 11115 } 11116 ast_mutex_unlock(&iflock); 11117 return c; 11118 }
static char * complete_sipnotify | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 11185 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
11186 { 11187 char *c = NULL; 11188 11189 if (pos == 2) { 11190 int which = 0; 11191 char *cat = NULL; 11192 int wordlen = strlen(word); 11193 11194 /* do completion for notify type */ 11195 11196 if (!notify_types) 11197 return NULL; 11198 11199 while ( (cat = ast_category_browse(notify_types, cat)) ) { 11200 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 11201 c = ast_strdup(cat); 11202 break; 11203 } 11204 } 11205 return c; 11206 } 11207 11208 if (pos > 2) 11209 return complete_sip_peer(word, state, 0); 11210 11211 return NULL; 11212 }
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 5808 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
05809 { 05810 int start = 0; 05811 int copied = 0; 05812 for (;;) { 05813 const char *tmp = __get_header(orig, field, &start); 05814 05815 if (ast_strlen_zero(tmp)) 05816 break; 05817 /* Add what we're responding to */ 05818 add_header(req, field, tmp); 05819 copied++; 05820 } 05821 return copied ? 0 : -1; 05822 }
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 5797 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
05798 { 05799 const char *tmp = get_header(orig, field); 05800 05801 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 05802 return add_header(req, field, tmp); 05803 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 05804 return -1; 05805 }
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 6857 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().
06858 { 06859 long offset; 06860 int x; 06861 offset = ((void *)dst) - ((void *)src); 06862 /* First copy stuff */ 06863 memcpy(dst, src, sizeof(*dst)); 06864 /* Now fix pointer arithmetic */ 06865 for (x=0; x < src->headers; x++) 06866 dst->header[x] += offset; 06867 for (x=0; x < src->lines; x++) 06868 dst->line[x] += offset; 06869 dst->rlPart1 += offset; 06870 dst->rlPart2 += offset; 06871 }
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 5830 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().
05831 { 05832 int copied = 0; 05833 int start = 0; 05834 05835 for (;;) { 05836 char new[512]; 05837 const char *oh = __get_header(orig, field, &start); 05838 05839 if (ast_strlen_zero(oh)) 05840 break; 05841 05842 if (!copied) { /* Only check for empty rport in topmost via header */ 05843 char leftmost[512], *others, *rport; 05844 05845 /* Only work on leftmost value */ 05846 ast_copy_string(leftmost, oh, sizeof(leftmost)); 05847 others = strchr(leftmost, ','); 05848 if (others) 05849 *others++ = '\0'; 05850 05851 /* Find ;rport; (empty request) */ 05852 rport = strstr(leftmost, ";rport"); 05853 if (rport && *(rport+6) == '=') 05854 rport = NULL; /* We already have a parameter to rport */ 05855 05856 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 05857 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 05858 /* We need to add received port - rport */ 05859 char *end; 05860 05861 rport = strstr(leftmost, ";rport"); 05862 05863 if (rport) { 05864 end = strchr(rport + 1, ';'); 05865 if (end) 05866 memmove(rport, end, strlen(end) + 1); 05867 else 05868 *rport = '\0'; 05869 } 05870 05871 /* Add rport to first VIA header if requested */ 05872 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 05873 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05874 ntohs(p->recv.sin_port), 05875 others ? "," : "", others ? others : ""); 05876 } else { 05877 /* We should *always* add a received to the topmost via */ 05878 snprintf(new, sizeof(new), "%s;received=%s%s%s", 05879 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05880 others ? "," : "", others ? others : ""); 05881 } 05882 oh = new; /* the header to copy */ 05883 } /* else add the following via headers untouched */ 05884 add_header(req, field, oh); 05885 copied++; 05886 } 05887 if (!copied) { 05888 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 05889 return -1; 05890 } 05891 return 0; 05892 }
static int create_addr | ( | struct sip_pvt * | dialog, | |
const char * | opeer | |||
) | [static] |
create address structure from peer name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success
Definition at line 2909 of file chan_sip.c.
References ahp, ast_copy_string(), ast_get_srv(), ast_gethostbyname(), ast_log(), ast_string_field_set, ASTOBJ_UNREF, create_addr_from_peer(), find_peer(), hp, portno, sip_pvt::recv, sip_pvt::sa, sip_destroy_peer(), STANDARD_SIP_PORT, sip_pvt::timer_t1, and sip_peer::tohost.
02910 { 02911 struct hostent *hp; 02912 struct ast_hostent ahp; 02913 struct sip_peer *p; 02914 char *port; 02915 int portno; 02916 char host[MAXHOSTNAMELEN], *hostn; 02917 char peer[256]; 02918 02919 ast_copy_string(peer, opeer, sizeof(peer)); 02920 port = strchr(peer, ':'); 02921 if (port) 02922 *port++ = '\0'; 02923 dialog->sa.sin_family = AF_INET; 02924 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 02925 p = find_peer(peer, NULL, 1, 0); 02926 02927 if (p) { 02928 int res = create_addr_from_peer(dialog, p); 02929 if (port) { 02930 portno = atoi(port); 02931 dialog->sa.sin_port = dialog->recv.sin_port = htons(portno); 02932 } 02933 ASTOBJ_UNREF(p, sip_destroy_peer); 02934 return res; 02935 } 02936 hostn = peer; 02937 portno = port ? atoi(port) : STANDARD_SIP_PORT; 02938 if (srvlookup) { 02939 char service[MAXHOSTNAMELEN]; 02940 int tportno; 02941 int ret; 02942 02943 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 02944 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 02945 if (ret > 0) { 02946 hostn = host; 02947 portno = tportno; 02948 } 02949 } 02950 hp = ast_gethostbyname(hostn, &ahp); 02951 if (!hp) { 02952 ast_log(LOG_WARNING, "No such host: %s\n", peer); 02953 return -1; 02954 } 02955 ast_string_field_set(dialog, tohost, peer); 02956 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 02957 dialog->sa.sin_port = htons(portno); 02958 dialog->recv = dialog->sa; 02959 return 0; 02960 }
Create address structure from peer reference. return -1 on error, 0 on success.
Definition at line 2800 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().
02801 { 02802 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 02803 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 02804 dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr; 02805 dialog->recv = dialog->sa; 02806 } else 02807 return -1; 02808 02809 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 02810 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 02811 dialog->capability = peer->capability; 02812 if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) { 02813 ast_rtp_destroy(dialog->vrtp); 02814 dialog->vrtp = NULL; 02815 } 02816 dialog->prefs = peer->prefs; 02817 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) { 02818 dialog->t38.capability = global_t38_capability; 02819 if (dialog->udptl) { 02820 if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC ) 02821 dialog->t38.capability |= T38FAX_UDP_EC_FEC; 02822 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY ) 02823 dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 02824 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE ) 02825 dialog->t38.capability |= T38FAX_UDP_EC_NONE; 02826 dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 02827 if (option_debug > 1) 02828 ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability); 02829 } 02830 dialog->t38.jointcapability = dialog->t38.capability; 02831 } else if (dialog->udptl) { 02832 ast_udptl_destroy(dialog->udptl); 02833 dialog->udptl = NULL; 02834 } 02835 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE ); 02836 02837 if (dialog->rtp) { 02838 ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 02839 ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 02840 ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); 02841 ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); 02842 ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); 02843 /* Set Frame packetization */ 02844 ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); 02845 dialog->autoframing = peer->autoframing; 02846 } 02847 if (dialog->vrtp) { 02848 ast_rtp_setdtmf(dialog->vrtp, 0); 02849 ast_rtp_setdtmfcompensate(dialog->vrtp, 0); 02850 ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); 02851 ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); 02852 ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); 02853 } 02854 02855 ast_string_field_set(dialog, peername, peer->name); 02856 ast_string_field_set(dialog, authname, peer->username); 02857 ast_string_field_set(dialog, username, peer->username); 02858 ast_string_field_set(dialog, peersecret, peer->secret); 02859 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 02860 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 02861 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 02862 ast_string_field_set(dialog, tohost, peer->tohost); 02863 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 02864 if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 02865 char *tmpcall; 02866 char *c; 02867 tmpcall = ast_strdupa(dialog->callid); 02868 c = strchr(tmpcall, '@'); 02869 if (c) { 02870 *c = '\0'; 02871 ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain); 02872 } 02873 } 02874 if (ast_strlen_zero(dialog->tohost)) 02875 ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr)); 02876 if (!ast_strlen_zero(peer->fromdomain)) 02877 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 02878 if (!ast_strlen_zero(peer->fromuser)) 02879 ast_string_field_set(dialog, fromuser, peer->fromuser); 02880 if (!ast_strlen_zero(peer->language)) 02881 ast_string_field_set(dialog, language, peer->language); 02882 dialog->maxtime = peer->maxms; 02883 dialog->callgroup = peer->callgroup; 02884 dialog->pickupgroup = peer->pickupgroup; 02885 dialog->peerauth = peer->auth; 02886 dialog->allowtransfer = peer->allowtransfer; 02887 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 02888 /* Minimum is settable or default to 100 ms */ 02889 if (peer->maxms && peer->lastms) 02890 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 02891 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 02892 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 02893 dialog->noncodeccapability |= AST_RTP_DTMF; 02894 else 02895 dialog->noncodeccapability &= ~AST_RTP_DTMF; 02896 dialog->jointnoncodeccapability = dialog->noncodeccapability; 02897 ast_string_field_set(dialog, context, peer->context); 02898 dialog->rtptimeout = peer->rtptimeout; 02899 if (peer->call_limit) 02900 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 02901 dialog->maxcallbitrate = peer->maxcallbitrate; 02902 02903 return 0; 02904 }
static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 8050 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().
08051 { 08052 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 08053 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08054 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL); 08055 else 08056 ast_db_del("SIP/Registry", peer->name); 08057 } 08058 }
static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 6901 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().
06902 { 06903 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 06904 06905 if (!*e) 06906 return -1; 06907 req->rlPart1 = e; /* method or protocol */ 06908 e = ast_skip_nonblanks(e); 06909 if (*e) 06910 *e++ = '\0'; 06911 /* Get URI or status code */ 06912 e = ast_skip_blanks(e); 06913 if ( !*e ) 06914 return -1; 06915 ast_trim_blanks(e); 06916 06917 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 06918 if (strlen(e) < 3) /* status code is 3 digits */ 06919 return -1; 06920 req->rlPart2 = e; 06921 } else { /* We have a request */ 06922 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 06923 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 06924 e++; 06925 if (!*e) 06926 return -1; 06927 } 06928 req->rlPart2 = e; /* URI */ 06929 e = ast_skip_nonblanks(e); 06930 if (*e) 06931 *e++ = '\0'; 06932 e = ast_skip_blanks(e); 06933 if (strcasecmp(e, "SIP/2.0") ) { 06934 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 06935 return -1; 06936 } 06937 } 06938 return 1; 06939 }
static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 16259 of file chan_sip.c.
References __sip_destroy(), ast_channel_trylock, ast_channel_unlock, ast_io_add(), ast_io_change(), AST_IO_IN, ast_io_remove(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_rtp_get_rtpholdtimeout(), ast_rtp_get_rtpkeepalive(), ast_rtp_get_rtptimeout(), ast_rtp_sendcng(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtptimeout(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, ast_verbose(), DEADLOCK_AVOIDANCE, FALSE, sip_pvt::flags, iflist, iflock, io, sip_pvt::lock, LOG_NOTICE, sip_pvt::next, option_verbose, sip_pvt::owner, sip_pvt::packets, sip_do_reload(), SIP_NEEDDESTROY, sip_reload_lock, sipsock, sipsock_read(), t, T38_ENABLED, and VERBOSE_PREFIX_1.
16260 { 16261 int res; 16262 struct sip_pvt *sip; 16263 struct sip_peer *peer = NULL; 16264 time_t t; 16265 int fastrestart = FALSE; 16266 int lastpeernum = -1; 16267 int curpeernum; 16268 int reloading; 16269 16270 /* Add an I/O event to our SIP UDP socket */ 16271 if (sipsock > -1) 16272 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 16273 16274 /* From here on out, we die whenever asked */ 16275 for(;;) { 16276 /* Check for a reload request */ 16277 ast_mutex_lock(&sip_reload_lock); 16278 reloading = sip_reloading; 16279 sip_reloading = FALSE; 16280 ast_mutex_unlock(&sip_reload_lock); 16281 if (reloading) { 16282 if (option_verbose > 0) 16283 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 16284 sip_do_reload(sip_reloadreason); 16285 16286 /* Change the I/O fd of our UDP socket */ 16287 if (sipsock > -1) { 16288 if (sipsock_read_id) 16289 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 16290 else 16291 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 16292 } else if (sipsock_read_id) { 16293 ast_io_remove(io, sipsock_read_id); 16294 sipsock_read_id = NULL; 16295 } 16296 } 16297 restartsearch: 16298 /* Check for interfaces needing to be killed */ 16299 ast_mutex_lock(&iflock); 16300 t = time(NULL); 16301 /* don't scan the interface list if it hasn't been a reasonable period 16302 of time since the last time we did it (when MWI is being sent, we can 16303 get back to this point every millisecond or less) 16304 */ 16305 for (sip = iflist; !fastrestart && sip; sip = sip->next) { 16306 /*! \note If we can't get a lock on an interface, skip it and come 16307 * back later. Note that there is the possibility of a deadlock with 16308 * sip_hangup otherwise, because sip_hangup is called with the channel 16309 * locked first, and the iface lock is attempted second. 16310 */ 16311 if (ast_mutex_trylock(&sip->lock)) 16312 continue; 16313 16314 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 16315 if (sip->rtp && sip->owner && 16316 (sip->owner->_state == AST_STATE_UP) && 16317 !sip->redirip.sin_addr.s_addr && 16318 sip->t38.state != T38_ENABLED) { 16319 if (sip->lastrtptx && 16320 ast_rtp_get_rtpkeepalive(sip->rtp) && 16321 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) { 16322 /* Need to send an empty RTP packet */ 16323 sip->lastrtptx = time(NULL); 16324 ast_rtp_sendcng(sip->rtp, 0); 16325 } 16326 if (sip->lastrtprx && 16327 (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) && 16328 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) { 16329 /* Might be a timeout now -- see if we're on hold */ 16330 struct sockaddr_in sin; 16331 ast_rtp_get_peer(sip->rtp, &sin); 16332 if (sin.sin_addr.s_addr || 16333 (ast_rtp_get_rtpholdtimeout(sip->rtp) && 16334 (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) { 16335 /* Needs a hangup */ 16336 if (ast_rtp_get_rtptimeout(sip->rtp)) { 16337 while (sip->owner && ast_channel_trylock(sip->owner)) { 16338 DEADLOCK_AVOIDANCE(&sip->lock); 16339 } 16340 if (sip->owner) { 16341 ast_log(LOG_NOTICE, 16342 "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 16343 sip->owner->name, 16344 (long) (t - sip->lastrtprx)); 16345 /* Issue a softhangup */ 16346 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 16347 ast_channel_unlock(sip->owner); 16348 /* forget the timeouts for this call, since a hangup 16349 has already been requested and we don't want to 16350 repeatedly request hangups 16351 */ 16352 ast_rtp_set_rtptimeout(sip->rtp, 0); 16353 ast_rtp_set_rtpholdtimeout(sip->rtp, 0); 16354 if (sip->vrtp) { 16355 ast_rtp_set_rtptimeout(sip->vrtp, 0); 16356 ast_rtp_set_rtpholdtimeout(sip->vrtp, 0); 16357 } 16358 } 16359 } 16360 } 16361 } 16362 } 16363 /* If we have sessions that needs to be destroyed, do it now */ 16364 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && 16365 !sip->owner) { 16366 ast_mutex_unlock(&sip->lock); 16367 __sip_destroy(sip, 1); 16368 ast_mutex_unlock(&iflock); 16369 usleep(1); 16370 goto restartsearch; 16371 } 16372 ast_mutex_unlock(&sip->lock); 16373 } 16374 ast_mutex_unlock(&iflock); 16375 16376 /* XXX TODO The scheduler usage in this module does not have sufficient 16377 * synchronization being done between running the scheduler and places 16378 * scheduling tasks. As it is written, any scheduled item may not run 16379 * any sooner than about 1 second, regardless of whether a sooner time 16380 * was asked for. */ 16381 16382 pthread_testcancel(); 16383 /* Wait for sched or io */ 16384 res = ast_sched_wait(sched); 16385 if ((res < 0) || (res > 1000)) 16386 res = 1000; 16387 /* If we might need to send more mailboxes, don't wait long at all.*/ 16388 if (fastrestart) 16389 res = 1; 16390 res = ast_io_wait(io, res); 16391 if (option_debug && res > 20) 16392 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 16393 ast_mutex_lock(&monlock); 16394 res = ast_sched_runq(sched); 16395 if (option_debug && res >= 20) 16396 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 16397 16398 /* Send MWI notifications to peers - static and cached realtime peers */ 16399 t = time(NULL); 16400 fastrestart = FALSE; 16401 curpeernum = 0; 16402 peer = NULL; 16403 /* Find next peer that needs mwi */ 16404 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 16405 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 16406 fastrestart = TRUE; 16407 lastpeernum = curpeernum; 16408 peer = ASTOBJ_REF(iterator); 16409 }; 16410 curpeernum++; 16411 } while (0) 16412 ); 16413 /* Send MWI to the peer */ 16414 if (peer) { 16415 ASTOBJ_WRLOCK(peer); 16416 sip_send_mwi_to_peer(peer); 16417 ASTOBJ_UNLOCK(peer); 16418 ASTOBJ_UNREF(peer,sip_destroy_peer); 16419 } else { 16420 /* Reset where we come from */ 16421 lastpeernum = -1; 16422 } 16423 ast_mutex_unlock(&monlock); 16424 } 16425 /* Never reached */ 16426 return NULL; 16427 16428 }
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 11695 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().
11696 { 11697 char digest[1024]; 11698 11699 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 11700 return -2; 11701 11702 p->authtries++; 11703 if (option_debug > 1) 11704 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 11705 memset(digest, 0, sizeof(digest)); 11706 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 11707 /* No way to authenticate */ 11708 return -1; 11709 } 11710 /* Now we have a reply digest */ 11711 p->options->auth = digest; 11712 p->options->authheader = respheader; 11713 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 11714 }
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 11674 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().
11675 { 11676 char digest[1024]; 11677 p->authtries++; 11678 memset(digest,0,sizeof(digest)); 11679 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 11680 /* There's nothing to use for authentication */ 11681 /* No digest challenge in request */ 11682 if (sip_debug_test_pvt(p) && p->registry) 11683 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 11684 /* No old challenge */ 11685 return -1; 11686 } 11687 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 11688 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 11689 if (sip_debug_test_pvt(p) && p->registry) 11690 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 11691 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 11692 }
static void do_setnat | ( | struct sip_pvt * | p, | |
int | natflags | |||
) | [static] |
Set nat mode on the various data sockets.
Definition at line 2776 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().
02777 { 02778 const char *mode = natflags ? "On" : "Off"; 02779 02780 if (p->rtp) { 02781 if (option_debug) 02782 ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode); 02783 ast_rtp_setnat(p->rtp, natflags); 02784 } 02785 if (p->vrtp) { 02786 if (option_debug) 02787 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode); 02788 ast_rtp_setnat(p->vrtp, natflags); 02789 } 02790 if (p->udptl) { 02791 if (option_debug) 02792 ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode); 02793 ast_udptl_setnat(p->udptl, natflags); 02794 } 02795 }
static int does_peer_need_mwi | ( | struct sip_peer * | peer | ) | [static] |
Check whether peer needs a new MWI notification check.
Definition at line 16238 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.
16239 { 16240 time_t t = time(NULL); 16241 16242 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 16243 !peer->mwipvt) { /* We don't have a subscription */ 16244 peer->lastmsgcheck = t; /* Reset timer */ 16245 return FALSE; 16246 } 16247 16248 if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime) 16249 return TRUE; 16250 16251 return FALSE; 16252 }
static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 10522 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
10523 { 10524 switch (mode) { 10525 case SIP_DOMAIN_AUTO: 10526 return "[Automatic]"; 10527 case SIP_DOMAIN_CONFIG: 10528 return "[Configured]"; 10529 } 10530 10531 return ""; 10532 }
static const char * dtmfmode2str | ( | int | mode | ) | const [static] |
Convert DTMF mode to printable string.
Definition at line 10302 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().
10303 { 10304 switch (mode) { 10305 case SIP_DTMF_RFC2833: 10306 return "rfc2833"; 10307 case SIP_DTMF_INFO: 10308 return "info"; 10309 case SIP_DTMF_INBAND: 10310 return "inband"; 10311 case SIP_DTMF_AUTO: 10312 return "auto"; 10313 } 10314 return "<error>"; 10315 }
static int expire_register | ( | const void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 8061 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().
08062 { 08063 struct sip_peer *peer = (struct sip_peer *)data; 08064 08065 if (!peer) /* Hmmm. We have no peer. Weird. */ 08066 return 0; 08067 08068 memset(&peer->addr, 0, sizeof(peer->addr)); 08069 08070 destroy_association(peer); /* remove registration data from storage */ 08071 08072 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08073 register_peer_exten(peer, FALSE); /* Remove regexten */ 08074 peer->expire = -1; 08075 ast_device_state_changed("SIP/%s", peer->name); 08076 08077 /* Do we need to release this peer from memory? 08078 Only for realtime peers and autocreated peers 08079 */ 08080 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) || 08081 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 08082 struct sip_peer *peer_ptr = peer_ptr; 08083 peer_ptr = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); 08084 if (peer_ptr) { 08085 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08086 } 08087 } 08088 08089 ASTOBJ_UNREF(peer, sip_destroy_peer); 08090 08091 return 0; 08092 }
static void extract_uri | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Check Contact: URI of SIP message.
Definition at line 6991 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().
06992 { 06993 char stripped[SIPBUFSIZE]; 06994 char *c; 06995 06996 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 06997 c = get_in_brackets(stripped); 06998 c = strsep(&c, ";"); /* trim ; and beyond */ 06999 if (!ast_strlen_zero(c)) 07000 ast_string_field_set(p, uri, c); 07001 }
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 4297 of file chan_sip.c.
References aliases.
04298 { 04299 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 04300 static const struct cfalias { 04301 char * const fullname; 04302 char * const shortname; 04303 } aliases[] = { 04304 { "Content-Type", "c" }, 04305 { "Content-Encoding", "e" }, 04306 { "From", "f" }, 04307 { "Call-ID", "i" }, 04308 { "Contact", "m" }, 04309 { "Content-Length", "l" }, 04310 { "Subject", "s" }, 04311 { "To", "t" }, 04312 { "Supported", "k" }, 04313 { "Refer-To", "r" }, 04314 { "Referred-By", "b" }, 04315 { "Allow-Events", "u" }, 04316 { "Event", "o" }, 04317 { "Via", "v" }, 04318 { "Accept-Contact", "a" }, 04319 { "Reject-Contact", "j" }, 04320 { "Request-Disposition", "d" }, 04321 { "Session-Expires", "x" }, 04322 { "Identity", "y" }, 04323 { "Identity-Info", "n" }, 04324 }; 04325 int x; 04326 04327 for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 04328 if (!strcasecmp(aliases[x].fullname, name)) 04329 return aliases[x].shortname; 04330 04331 return _default; 04332 }
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 4659 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().
04660 { 04661 struct sip_pvt *p = NULL; 04662 char *tag = ""; /* note, tag is never NULL */ 04663 char totag[128]; 04664 char fromtag[128]; 04665 const char *callid = get_header(req, "Call-ID"); 04666 const char *from = get_header(req, "From"); 04667 const char *to = get_header(req, "To"); 04668 const char *cseq = get_header(req, "Cseq"); 04669 04670 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 04671 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 04672 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 04673 ast_strlen_zero(from) || ast_strlen_zero(cseq)) 04674 return NULL; /* Invalid packet */ 04675 04676 if (pedanticsipchecking) { 04677 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 04678 we need more to identify a branch - so we have to check branch, from 04679 and to tags to identify a call leg. 04680 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 04681 in sip.conf 04682 */ 04683 if (gettag(req, "To", totag, sizeof(totag))) 04684 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 04685 gettag(req, "From", fromtag, sizeof(fromtag)); 04686 04687 tag = (req->method == SIP_RESPONSE) ? totag : fromtag; 04688 04689 if (option_debug > 4 ) 04690 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); 04691 } 04692 04693 ast_mutex_lock(&iflock); 04694 for (p = iflist; p; p = p->next) { 04695 /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 04696 int found = FALSE; 04697 if (ast_strlen_zero(p->callid)) 04698 continue; 04699 if (req->method == SIP_REGISTER) 04700 found = (!strcmp(p->callid, callid)); 04701 else { 04702 found = !strcmp(p->callid, callid); 04703 if (pedanticsipchecking && found) { 04704 found = ast_strlen_zero(tag) || ast_strlen_zero(p->theirtag) || !ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED) || !strcmp(p->theirtag, tag); 04705 } 04706 } 04707 04708 if (option_debug > 4) 04709 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); 04710 04711 /* If we get a new request within an existing to-tag - check the to tag as well */ 04712 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 04713 if (p->tag[0] == '\0' && totag[0]) { 04714 /* We have no to tag, but they have. Wrong dialog */ 04715 found = FALSE; 04716 } else if (totag[0]) { /* Both have tags, compare them */ 04717 if (strcmp(totag, p->tag)) { 04718 found = FALSE; /* This is not our packet */ 04719 } 04720 } 04721 if (!found && option_debug > 4) 04722 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); 04723 } 04724 if (found) { 04725 /* Found the call */ 04726 ast_mutex_lock(&p->lock); 04727 ast_mutex_unlock(&iflock); 04728 return p; 04729 } 04730 } 04731 ast_mutex_unlock(&iflock); 04732 04733 /* See if the method is capable of creating a dialog */ 04734 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 04735 if (intended_method == SIP_REFER) { 04736 /* We do support REFER, but not outside of a dialog yet */ 04737 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 04738 } else if (intended_method == SIP_NOTIFY) { 04739 /* We do not support out-of-dialog NOTIFY either, 04740 like voicemail notification, so cancel that early */ 04741 transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); 04742 } else { 04743 /* Ok, time to create a new SIP dialog object, a pvt */ 04744 if ((p = sip_alloc(callid, sin, 1, intended_method))) { 04745 /* Ok, we've created a dialog, let's go and process it */ 04746 ast_mutex_lock(&p->lock); 04747 } else { 04748 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 04749 getting a dialog from sip_alloc. 04750 04751 Without a dialog we can't retransmit and handle ACKs and all that, but at least 04752 send an error message. 04753 04754 Sorry, we apologize for the inconvienience 04755 */ 04756 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 04757 if (option_debug > 3) 04758 ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 04759 } 04760 } 04761 return p; 04762 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 04763 /* A method we do not support, let's take it on the volley */ 04764 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 04765 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 04766 /* This is a request outside of a dialog that we don't know about 04767 ...never reply to an ACK! 04768 */ 04769 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 04770 } 04771 /* We do not respond to responses for dialogs that we don't know about, we just drop 04772 the session quickly */ 04773 04774 return p; 04775 }
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 2337 of file chan_sip.c.
References s.
Referenced by get_in_brackets().
02338 { 02339 char last_char = '\0'; 02340 const char *s; 02341 for (s = start; *s && s != lim; last_char = *s++) { 02342 if (*s == '"' && last_char != '\\') 02343 break; 02344 } 02345 return s; 02346 }
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 2688 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().
02689 { 02690 struct sip_peer *p = NULL; 02691 02692 if (peer) 02693 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 02694 else 02695 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); 02696 02697 if (!p && (realtime || devstate_only)) 02698 p = realtime_peer(peer, sin, devstate_only); 02699 02700 return p; 02701 }
static struct sip_auth * find_realm_authentication | ( | struct sip_auth * | authlist, | |
const char * | realm | |||
) | [static] |
Find authentication for a specific realm.
Definition at line 17067 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
17068 { 17069 struct sip_auth *a; 17070 17071 for (a = authlist; a; a = a->next) { 17072 if (!strcasecmp(a->realm, realm)) 17073 break; 17074 } 17075 17076 return a; 17077 }
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 4992 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().
04993 { 04994 const char *content_type; 04995 const char *content_length; 04996 const char *search; 04997 char *boundary; 04998 unsigned int x; 04999 int boundaryisquoted = FALSE; 05000 int found_application_sdp = FALSE; 05001 int found_end_of_headers = FALSE; 05002 05003 content_length = get_header(req, "Content-Length"); 05004 05005 if (!ast_strlen_zero(content_length)) { 05006 if (sscanf(content_length, "%ud", &x) != 1) { 05007 ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length); 05008 return 0; 05009 } 05010 05011 /* Content-Length of zero means there can't possibly be an 05012 SDP here, even if the Content-Type says there is */ 05013 if (x == 0) 05014 return 0; 05015 } 05016 05017 content_type = get_header(req, "Content-Type"); 05018 05019 /* if the body contains only SDP, this is easy */ 05020 if (!strncasecmp(content_type, "application/sdp", 15)) { 05021 req->sdp_start = 0; 05022 req->sdp_end = req->lines; 05023 return req->lines ? 1 : 0; 05024 } 05025 05026 /* if it's not multipart/mixed, there cannot be an SDP */ 05027 if (strncasecmp(content_type, "multipart/mixed", 15)) 05028 return 0; 05029 05030 /* if there is no boundary marker, it's invalid */ 05031 if ((search = strcasestr(content_type, ";boundary="))) 05032 search += 10; 05033 else if ((search = strcasestr(content_type, "; boundary="))) 05034 search += 11; 05035 else 05036 return 0; 05037 05038 if (ast_strlen_zero(search)) 05039 return 0; 05040 05041 /* If the boundary is quoted with ", remove quote */ 05042 if (*search == '\"') { 05043 search++; 05044 boundaryisquoted = TRUE; 05045 } 05046 05047 /* make a duplicate of the string, with two extra characters 05048 at the beginning */ 05049 boundary = ast_strdupa(search - 2); 05050 boundary[0] = boundary[1] = '-'; 05051 /* Remove final quote */ 05052 if (boundaryisquoted) 05053 boundary[strlen(boundary) - 1] = '\0'; 05054 05055 /* search for the boundary marker, the empty line delimiting headers from 05056 sdp part and the end boundry if it exists */ 05057 05058 for (x = 0; x < (req->lines ); x++) { 05059 if(!strncasecmp(req->line[x], boundary, strlen(boundary))){ 05060 if(found_application_sdp && found_end_of_headers){ 05061 req->sdp_end = x-1; 05062 return 1; 05063 } 05064 found_application_sdp = FALSE; 05065 } 05066 if(!strcasecmp(req->line[x], "Content-Type: application/sdp")) 05067 found_application_sdp = TRUE; 05068 05069 if(strlen(req->line[x]) == 0 ){ 05070 if(found_application_sdp && !found_end_of_headers){ 05071 req->sdp_start = x; 05072 found_end_of_headers = TRUE; 05073 } 05074 } 05075 } 05076 if(found_application_sdp && found_end_of_headers) { 05077 req->sdp_end = x; 05078 return TRUE; 05079 } 05080 return FALSE; 05081 }
static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 1695 of file chan_sip.c.
References ast_strlen_zero(), method_match(), and sip_methods.
Referenced by __sip_pretend_ack(), handle_response(), and sipsock_read().
01696 { 01697 int i, res = 0; 01698 01699 if (ast_strlen_zero(msg)) 01700 return 0; 01701 for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) { 01702 if (method_match(i, msg)) 01703 res = sip_methods[i].id; 01704 } 01705 return res; 01706 }
static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static] |
Find subscription type in array.
Definition at line 11010 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
11011 { 11012 int i; 11013 11014 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 11015 if (subscription_types[i].type == subtype) { 11016 return &subscription_types[i]; 11017 } 11018 } 11019 return &subscription_types[0]; 11020 }
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 2767 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.
02768 { 02769 struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name); 02770 if (!u && realtime) 02771 u = realtime_user(name); 02772 return u; 02773 }
static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 8440 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
08441 { 08442 struct sip_route *next; 08443 08444 while (route) { 08445 next = route->next; 08446 free(route); 08447 route = next; 08448 } 08449 }
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 12030 of file chan_sip.c.
References ast_copy_string(), ast_log(), ast_strlen_zero(), and check_sip_domain().
12031 { 12032 if (ast_strlen_zero(data)) { 12033 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 12034 return -1; 12035 } 12036 if (check_sip_domain(data, NULL, 0)) 12037 ast_copy_string(buf, data, len); 12038 else 12039 buf[0] = '\0'; 12040 return 0; 12041 }
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 11966 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.
11967 { 11968 struct sip_pvt *p; 11969 const char *content = NULL; 11970 AST_DECLARE_APP_ARGS(args, 11971 AST_APP_ARG(header); 11972 AST_APP_ARG(number); 11973 ); 11974 int i, number, start = 0; 11975 11976 if (ast_strlen_zero(data)) { 11977 ast_log(LOG_WARNING, "This function requires a header name.\n"); 11978 return -1; 11979 } 11980 11981 ast_channel_lock(chan); 11982 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11983 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11984 ast_channel_unlock(chan); 11985 return -1; 11986 } 11987 11988 AST_STANDARD_APP_ARGS(args, data); 11989 if (!args.number) { 11990 number = 1; 11991 } else { 11992 sscanf(args.number, "%d", &number); 11993 if (number < 1) 11994 number = 1; 11995 } 11996 11997 p = chan->tech_pvt; 11998 11999 /* If there is no private structure, this channel is no longer alive */ 12000 if (!p) { 12001 ast_channel_unlock(chan); 12002 return -1; 12003 } 12004 12005 for (i = 0; i < number; i++) 12006 content = __get_header(&p->initreq, args.header, &start); 12007 12008 if (ast_strlen_zero(content)) { 12009 ast_channel_unlock(chan); 12010 return -1; 12011 } 12012 12013 ast_copy_string(buf, content, len); 12014 ast_channel_unlock(chan); 12015 12016 return 0; 12017 }
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 12149 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.
12150 { 12151 struct sip_pvt *p; 12152 12153 *buf = 0; 12154 12155 if (!data) { 12156 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 12157 return -1; 12158 } 12159 12160 ast_channel_lock(chan); 12161 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 12162 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 12163 ast_channel_unlock(chan); 12164 return -1; 12165 } 12166 12167 p = chan->tech_pvt; 12168 12169 /* If there is no private structure, this channel is no longer alive */ 12170 if (!p) { 12171 ast_channel_unlock(chan); 12172 return -1; 12173 } 12174 12175 if (!strcasecmp(data, "peerip")) { 12176 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 12177 } else if (!strcasecmp(data, "recvip")) { 12178 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 12179 } else if (!strcasecmp(data, "from")) { 12180 ast_copy_string(buf, p->from, len); 12181 } else if (!strcasecmp(data, "uri")) { 12182 ast_copy_string(buf, p->uri, len); 12183 } else if (!strcasecmp(data, "useragent")) { 12184 ast_copy_string(buf, p->useragent, len); 12185 } else if (!strcasecmp(data, "peername")) { 12186 ast_copy_string(buf, p->peername, len); 12187 } else if (!strcasecmp(data, "t38passthrough")) { 12188 if (p->t38.state == T38_DISABLED) 12189 ast_copy_string(buf, "0", sizeof("0")); 12190 else /* T38 is offered or enabled in this call */ 12191 ast_copy_string(buf, "1", sizeof("1")); 12192 } else { 12193 ast_channel_unlock(chan); 12194 return -1; 12195 } 12196 ast_channel_unlock(chan); 12197 12198 return 0; 12199 }
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 12055 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.
12056 { 12057 struct sip_peer *peer; 12058 char *colname; 12059 12060 if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */ 12061 *colname++ = '\0'; 12062 else if ((colname = strchr(data, '|'))) 12063 *colname++ = '\0'; 12064 else 12065 colname = "ip"; 12066 12067 if (!(peer = find_peer(data, NULL, 1, 0))) 12068 return -1; 12069 12070 if (!strcasecmp(colname, "ip")) { 12071 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 12072 } else if (!strcasecmp(colname, "status")) { 12073 peer_status(peer, buf, len); 12074 } else if (!strcasecmp(colname, "language")) { 12075 ast_copy_string(buf, peer->language, len); 12076 } else if (!strcasecmp(colname, "regexten")) { 12077 ast_copy_string(buf, peer->regexten, len); 12078 } else if (!strcasecmp(colname, "limit")) { 12079 snprintf(buf, len, "%d", peer->call_limit); 12080 } else if (!strcasecmp(colname, "curcalls")) { 12081 snprintf(buf, len, "%d", peer->inUse); 12082 } else if (!strcasecmp(colname, "accountcode")) { 12083 ast_copy_string(buf, peer->accountcode, len); 12084 } else if (!strcasecmp(colname, "useragent")) { 12085 ast_copy_string(buf, peer->useragent, len); 12086 } else if (!strcasecmp(colname, "mailbox")) { 12087 ast_copy_string(buf, peer->mailbox, len); 12088 } else if (!strcasecmp(colname, "context")) { 12089 ast_copy_string(buf, peer->context, len); 12090 } else if (!strcasecmp(colname, "expire")) { 12091 snprintf(buf, len, "%d", peer->expire); 12092 } else if (!strcasecmp(colname, "dynamic")) { 12093 ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 12094 } else if (!strcasecmp(colname, "callerid_name")) { 12095 ast_copy_string(buf, peer->cid_name, len); 12096 } else if (!strcasecmp(colname, "callerid_num")) { 12097 ast_copy_string(buf, peer->cid_num, len); 12098 } else if (!strcasecmp(colname, "codecs")) { 12099 ast_getformatname_multiple(buf, len -1, peer->capability); 12100 } else if (!strncasecmp(colname, "codec[", 6)) { 12101 char *codecnum; 12102 int index = 0, codec = 0; 12103 12104 codecnum = colname + 6; /* move past the '[' */ 12105 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 12106 index = atoi(codecnum); 12107 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 12108 ast_copy_string(buf, ast_getformatname(codec), len); 12109 } else { 12110 buf[0] = '\0'; 12111 } 12112 } else { 12113 buf[0] = '\0'; 12114 } 12115 12116 ASTOBJ_UNREF(peer, sip_destroy_peer); 12117 12118 return 0; 12119 }
static char * generate_random_string | ( | char * | buf, | |
size_t | size | |||
) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 4487 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), and build_callid_registry().
04488 { 04489 long val[4]; 04490 int x; 04491 04492 for (x=0; x<4; x++) 04493 val[x] = ast_random(); 04494 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 04495 04496 return buf; 04497 }
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 9373 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().
09374 { 09375 char tmp[256] = "", *c, *a; 09376 struct sip_request *req = oreq ? oreq : &p->initreq; 09377 struct sip_refer *referdata = NULL; 09378 const char *transfer_context = NULL; 09379 09380 if (!p->refer && !sip_refer_allocate(p)) 09381 return -1; 09382 09383 referdata = p->refer; 09384 09385 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 09386 c = get_in_brackets(tmp); 09387 09388 if (pedanticsipchecking) 09389 ast_uri_decode(c); 09390 09391 if (strncasecmp(c, "sip:", 4)) { 09392 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 09393 return -1; 09394 } 09395 c += 4; 09396 if ((a = strchr(c, ';'))) /* Remove arguments */ 09397 *a = '\0'; 09398 09399 if ((a = strchr(c, '@'))) { /* Separate Domain */ 09400 *a++ = '\0'; 09401 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 09402 } 09403 09404 if (sip_debug_test_pvt(p)) 09405 ast_verbose("Looking for %s in %s\n", c, p->context); 09406 09407 if (p->owner) /* Mimic behaviour in res_features.c */ 09408 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 09409 09410 /* By default, use the context in the channel sending the REFER */ 09411 if (ast_strlen_zero(transfer_context)) { 09412 transfer_context = S_OR(p->owner->macrocontext, 09413 S_OR(p->context, default_context)); 09414 } 09415 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 09416 /* This is a blind transfer */ 09417 if (option_debug) 09418 ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 09419 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 09420 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 09421 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 09422 referdata->refer_call = NULL; 09423 /* Set new context */ 09424 ast_string_field_set(p, context, transfer_context); 09425 return 0; 09426 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 09427 return 1; 09428 } 09429 09430 return -1; 09431 }
static char* get_body | ( | struct sip_request * | req, | |
char * | name | |||
) | [static] |
Get a specific line from the message body.
Definition at line 4281 of file chan_sip.c.
References get_body_by_line(), len(), sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
04282 { 04283 int x; 04284 int len = strlen(name); 04285 char *r; 04286 04287 for (x = 0; x < req->lines; x++) { 04288 r = get_body_by_line(req->line[x], name, len); 04289 if (r[0] != '\0') 04290 return r; 04291 } 04292 04293 return ""; 04294 }
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 4247 of file chan_sip.c.
References ast_skip_blanks().
Referenced by get_body(), and get_sdp_iterate().
04248 { 04249 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') 04250 return ast_skip_blanks(line + nameLen + 1); 04251 04252 return ""; 04253 }
static char * get_calleridname | ( | const char * | input, | |
char * | output, | |||
size_t | outputsize | |||
) | [static] |
Get caller id name from SIP headers.
Definition at line 9485 of file chan_sip.c.
References ast_copy_string(), and ast_skip_blanks().
Referenced by check_user_full().
09486 { 09487 const char *end = strchr(input,'<'); /* first_bracket */ 09488 const char *tmp = strchr(input,'"'); /* first quote */ 09489 int bytes = 0; 09490 int maxbytes = outputsize - 1; 09491 09492 if (!end || end == input) /* we require a part in brackets */ 09493 return NULL; 09494 09495 end--; /* move just before "<" */ 09496 09497 if (tmp && tmp <= end) { 09498 /* The quote (tmp) precedes the bracket (end+1). 09499 * Find the matching quote and return the content. 09500 */ 09501 end = strchr(tmp+1, '"'); 09502 if (!end) 09503 return NULL; 09504 bytes = (int) (end - tmp); 09505 /* protect the output buffer */ 09506 if (bytes > maxbytes) 09507 bytes = maxbytes; 09508 ast_copy_string(output, tmp + 1, bytes); 09509 } else { 09510 /* No quoted string, or it is inside brackets. */ 09511 /* clear the empty characters in the begining*/ 09512 input = ast_skip_blanks(input); 09513 /* clear the empty characters in the end */ 09514 while(*end && *end < 33 && end > input) 09515 end--; 09516 if (end >= input) { 09517 bytes = (int) (end - input) + 2; 09518 /* protect the output buffer */ 09519 if (bytes > maxbytes) 09520 bytes = maxbytes; 09521 ast_copy_string(output, input, bytes); 09522 } else 09523 return NULL; 09524 } 09525 return output; 09526 }
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 9020 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().
09021 { 09022 char tmp[256] = "", *uri, *a; 09023 char tmpf[256] = "", *from; 09024 struct sip_request *req; 09025 char *colon; 09026 char *decoded_uri; 09027 09028 req = oreq; 09029 if (!req) 09030 req = &p->initreq; 09031 09032 /* Find the request URI */ 09033 if (req->rlPart2) 09034 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 09035 09036 if (pedanticsipchecking) 09037 ast_uri_decode(tmp); 09038 09039 uri = get_in_brackets(tmp); 09040 09041 if (strncasecmp(uri, "sip:", 4)) { 09042 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 09043 return -1; 09044 } 09045 uri += 4; 09046 09047 /* Now find the From: caller ID and name */ 09048 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 09049 if (!ast_strlen_zero(tmpf)) { 09050 if (pedanticsipchecking) 09051 ast_uri_decode(tmpf); 09052 from = get_in_brackets(tmpf); 09053 } else { 09054 from = NULL; 09055 } 09056 09057 if (!ast_strlen_zero(from)) { 09058 if (strncasecmp(from, "sip:", 4)) { 09059 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 09060 return -1; 09061 } 09062 from += 4; 09063 if ((a = strchr(from, '@'))) 09064 *a++ = '\0'; 09065 else 09066 a = from; /* just a domain */ 09067 from = strsep(&from, ";"); /* Remove userinfo options */ 09068 a = strsep(&a, ";"); /* Remove URI options */ 09069 ast_string_field_set(p, fromdomain, a); 09070 } 09071 09072 /* Skip any options and find the domain */ 09073 09074 /* Get the target domain */ 09075 if ((a = strchr(uri, '@'))) { 09076 *a++ = '\0'; 09077 } else { /* No username part */ 09078 a = uri; 09079 uri = "s"; /* Set extension to "s" */ 09080 } 09081 colon = strchr(a, ':'); /* Remove :port */ 09082 if (colon) 09083 *colon = '\0'; 09084 09085 uri = strsep(&uri, ";"); /* Remove userinfo options */ 09086 a = strsep(&a, ";"); /* Remove URI options */ 09087 09088 ast_string_field_set(p, domain, a); 09089 09090 if (!AST_LIST_EMPTY(&domain_list)) { 09091 char domain_context[AST_MAX_EXTENSION]; 09092 09093 domain_context[0] = '\0'; 09094 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 09095 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 09096 if (option_debug) 09097 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 09098 return -2; 09099 } 09100 } 09101 /* If we have a context defined, overwrite the original context */ 09102 if (!ast_strlen_zero(domain_context)) 09103 ast_string_field_set(p, context, domain_context); 09104 } 09105 09106 /* If the request coming in is a subscription and subscribecontext has been specified use it */ 09107 if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext)) 09108 ast_string_field_set(p, context, p->subscribecontext); 09109 09110 if (sip_debug_test_pvt(p)) 09111 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 09112 09113 /* If this is a subscription we actually just need to see if a hint exists for the extension */ 09114 if (req->method == SIP_SUBSCRIBE) { 09115 char hint[AST_MAX_EXTENSION]; 09116 return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1); 09117 } else { 09118 decoded_uri = ast_strdupa(uri); 09119 ast_uri_decode(decoded_uri); 09120 /* Check the dialplan for the username part of the request URI, 09121 the domain will be stored in the SIPDOMAIN variable 09122 Since extensions.conf can have unescaped characters, try matching a decoded 09123 uri in addition to the non-decoded uri 09124 Return 0 if we have a matching extension */ 09125 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)) || 09126 !strcmp(decoded_uri, ast_pickup_ext())) { 09127 if (!oreq) 09128 ast_string_field_set(p, exten, decoded_uri); 09129 return 0; 09130 } 09131 } 09132 09133 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 09134 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 09135 ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))) || 09136 !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri))) { 09137 return 1; 09138 } 09139 09140 return -1; 09141 }
static const char * get_header | ( | const struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get header from SIP request.
Definition at line 4370 of file chan_sip.c.
References __get_header().
04371 { 04372 int start = 0; 04373 return __get_header(req, name, &start); 04374 }
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 2359 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().
02360 { 02361 const char *parse = tmp; 02362 char *first_bracket; 02363 02364 /* 02365 * Skip any quoted text until we find the part in brackets. 02366 * On any error give up and return the full string. 02367 */ 02368 while ( (first_bracket = strchr(parse, '<')) ) { 02369 char *first_quote = strchr(parse, '"'); 02370 02371 if (!first_quote || first_quote > first_bracket) 02372 break; /* no need to look at quoted part */ 02373 /* the bracket is within quotes, so ignore it */ 02374 parse = find_closing_quote(first_quote + 1, NULL); 02375 if (!*parse) { /* not found, return full string ? */ 02376 /* XXX or be robust and return in-bracket part ? */ 02377 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 02378 break; 02379 } 02380 parse++; 02381 } 02382 if (first_bracket) { 02383 char *second_bracket = strchr(first_bracket + 1, '>'); 02384 if (second_bracket) { 02385 *second_bracket = '\0'; 02386 tmp = first_bracket + 1; 02387 } else { 02388 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 02389 } 02390 } 02391 return tmp; 02392 }
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 9895 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_notify(), and receive_message().
09896 { 09897 int x; 09898 int y; 09899 09900 buf[0] = '\0'; 09901 y = len - strlen(buf) - 5; 09902 if (y < 0) 09903 y = 0; 09904 for (x=0;x<req->lines;x++) { 09905 strncat(buf, req->line[x], y); /* safe */ 09906 y -= strlen(req->line[x]) + 1; 09907 if (y < 0) 09908 y = 0; 09909 if (y != 0) 09910 strcat(buf, "\n"); /* safe */ 09911 } 09912 return 0; 09913 }
static int get_rdnis | ( | struct sip_pvt * | p, | |
struct sip_request * | oreq | |||
) | [static] |
Get referring dnis.
Definition at line 8991 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().
08992 { 08993 char tmp[256], *c, *a; 08994 struct sip_request *req; 08995 08996 req = oreq; 08997 if (!req) 08998 req = &p->initreq; 08999 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 09000 if (ast_strlen_zero(tmp)) 09001 return 0; 09002 c = get_in_brackets(tmp); 09003 if (strncasecmp(c, "sip:", 4)) { 09004 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 09005 return -1; 09006 } 09007 c += 4; 09008 a = c; 09009 strsep(&a, "@;"); /* trim anything after @ or ; */ 09010 if (sip_debug_test_pvt(p)) 09011 ast_verbose("RDNIS is %s\n", c); 09012 ast_string_field_set(p, rdnis, c); 09013 09014 return 0; 09015 }
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 9207 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().
09208 { 09209 09210 const char *p_referred_by = NULL; 09211 char *h_refer_to = NULL; 09212 char *h_referred_by = NULL; 09213 char *refer_to; 09214 const char *p_refer_to; 09215 char *referred_by_uri = NULL; 09216 char *ptr; 09217 struct sip_request *req = NULL; 09218 const char *transfer_context = NULL; 09219 struct sip_refer *referdata; 09220 09221 09222 req = outgoing_req; 09223 referdata = transferer->refer; 09224 09225 if (!req) 09226 req = &transferer->initreq; 09227 09228 p_refer_to = get_header(req, "Refer-To"); 09229 if (ast_strlen_zero(p_refer_to)) { 09230 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 09231 return -2; /* Syntax error */ 09232 } 09233 h_refer_to = ast_strdupa(p_refer_to); 09234 refer_to = get_in_brackets(h_refer_to); 09235 if (pedanticsipchecking) 09236 ast_uri_decode(refer_to); 09237 09238 if (strncasecmp(refer_to, "sip:", 4)) { 09239 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 09240 return -3; 09241 } 09242 refer_to += 4; /* Skip sip: */ 09243 09244 /* Get referred by header if it exists */ 09245 p_referred_by = get_header(req, "Referred-By"); 09246 if (!ast_strlen_zero(p_referred_by)) { 09247 char *lessthan; 09248 h_referred_by = ast_strdupa(p_referred_by); 09249 if (pedanticsipchecking) 09250 ast_uri_decode(h_referred_by); 09251 09252 /* Store referrer's caller ID name */ 09253 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 09254 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 09255 *(lessthan - 1) = '\0'; /* Space */ 09256 } 09257 09258 referred_by_uri = get_in_brackets(h_referred_by); 09259 if(strncasecmp(referred_by_uri, "sip:", 4)) { 09260 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 09261 referred_by_uri = (char *) NULL; 09262 } else { 09263 referred_by_uri += 4; /* Skip sip: */ 09264 } 09265 } 09266 09267 /* Check for arguments in the refer_to header */ 09268 if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */ 09269 *ptr++ = '\0'; 09270 if (!strncasecmp(ptr, "REPLACES=", 9)) { 09271 char *to = NULL, *from = NULL; 09272 09273 /* This is an attended transfer */ 09274 referdata->attendedtransfer = 1; 09275 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 09276 ast_uri_decode(referdata->replaces_callid); 09277 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 09278 *ptr++ = '\0'; 09279 } 09280 09281 if (ptr) { 09282 /* Find the different tags before we destroy the string */ 09283 to = strcasestr(ptr, "to-tag="); 09284 from = strcasestr(ptr, "from-tag="); 09285 } 09286 09287 /* Grab the to header */ 09288 if (to) { 09289 ptr = to + 7; 09290 if ((to = strchr(ptr, '&'))) 09291 *to = '\0'; 09292 if ((to = strchr(ptr, ';'))) 09293 *to = '\0'; 09294 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 09295 } 09296 09297 if (from) { 09298 ptr = from + 9; 09299 if ((to = strchr(ptr, '&'))) 09300 *to = '\0'; 09301 if ((to = strchr(ptr, ';'))) 09302 *to = '\0'; 09303 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 09304 } 09305 09306 if (option_debug > 1) { 09307 if (!pedanticsipchecking) 09308 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 09309 else 09310 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>" ); 09311 } 09312 } 09313 } 09314 09315 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 09316 char *urioption = NULL, *domain; 09317 *ptr++ = '\0'; 09318 09319 if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */ 09320 *urioption++ = '\0'; 09321 09322 domain = ptr; 09323 if ((ptr = strchr(domain, ':'))) /* Remove :port */ 09324 *ptr = '\0'; 09325 09326 /* Save the domain for the dial plan */ 09327 ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain)); 09328 if (urioption) 09329 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 09330 } 09331 09332 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 09333 *ptr = '\0'; 09334 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 09335 09336 if (referred_by_uri) { 09337 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 09338 *ptr = '\0'; 09339 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 09340 } else { 09341 referdata->referred_by[0] = '\0'; 09342 } 09343 09344 /* Determine transfer context */ 09345 if (transferer->owner) /* Mimic behaviour in res_features.c */ 09346 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 09347 09348 /* By default, use the context in the channel sending the REFER */ 09349 if (ast_strlen_zero(transfer_context)) { 09350 transfer_context = S_OR(transferer->owner->macrocontext, 09351 S_OR(transferer->context, default_context)); 09352 } 09353 09354 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 09355 09356 /* Either an existing extension or the parking extension */ 09357 if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 09358 if (sip_debug_test_pvt(transferer)) { 09359 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 09360 } 09361 /* We are ready to transfer to the extension */ 09362 return 0; 09363 } 09364 if (sip_debug_test_pvt(transferer)) 09365 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 09366 09367 /* Failure, we can't find this extension */ 09368 return -1; 09369 }
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 9532 of file chan_sip.c.
References ast_copy_string(), and AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
09533 { 09534 char *start; 09535 char *end; 09536 09537 start = strchr(input,':'); 09538 if (!start) { 09539 output[0] = '\0'; 09540 return 0; 09541 } 09542 start++; 09543 09544 /* we found "number" */ 09545 ast_copy_string(output,start,maxlen); 09546 output[maxlen-1] = '\0'; 09547 09548 end = strchr(output,'@'); 09549 if (end) 09550 *end = '\0'; 09551 else 09552 output[0] = '\0'; 09553 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 09554 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 09555 09556 return 0; 09557 }
static const char * get_sdp | ( | struct sip_request * | req, | |
const char * | name | |||
) | [static] |
Get a line from an SDP message body.
Definition at line 4273 of file chan_sip.c.
References get_sdp_iterate().
04274 { 04275 int dummy = 0; 04276 04277 return get_sdp_iterate(&dummy, req, name); 04278 }
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 4259 of file chan_sip.c.
References get_body_by_line(), len(), and sip_request::line.
04260 { 04261 int len = strlen(name); 04262 04263 while (*start < req->sdp_end) { 04264 const char *r = get_body_by_line(req->line[(*start)++], name, len); 04265 if (r[0] != '\0') 04266 return r; 04267 } 04268 04269 return ""; 04270 }
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 9145 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().
09146 { 09147 struct sip_pvt *sip_pvt_ptr; 09148 09149 ast_mutex_lock(&iflock); 09150 09151 if (option_debug > 3 && totag) 09152 ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 09153 09154 /* Search interfaces and find the match */ 09155 for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 09156 if (!strcmp(sip_pvt_ptr->callid, callid)) { 09157 int match = 1; 09158 09159 /* Go ahead and lock it (and its owner) before returning */ 09160 ast_mutex_lock(&sip_pvt_ptr->lock); 09161 09162 /* Check if tags match. If not, this is not the call we want 09163 (With a forking SIP proxy, several call legs share the 09164 call id, but have different tags) 09165 */ 09166 if (pedanticsipchecking) { 09167 const char *pvt_fromtag, *pvt_totag; 09168 09169 if (ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_OUTGOING_CALL)) { 09170 /* Outgoing call tags : from is "our", to is "their" */ 09171 pvt_fromtag = sip_pvt_ptr->tag ; 09172 pvt_totag = sip_pvt_ptr->theirtag ; 09173 } else { 09174 /* Incoming call tags : from is "their", to is "our" */ 09175 pvt_fromtag = sip_pvt_ptr->theirtag ; 09176 pvt_totag = sip_pvt_ptr->tag ; 09177 } 09178 if (ast_strlen_zero(fromtag) || strcmp(fromtag, pvt_fromtag) || (!ast_strlen_zero(totag) && strcmp(totag, pvt_totag))) 09179 match = 0; 09180 } 09181 09182 if (!match) { 09183 ast_mutex_unlock(&sip_pvt_ptr->lock); 09184 continue; 09185 } 09186 09187 if (option_debug > 3 && totag) 09188 ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n", 09189 ast_test_flag(&sip_pvt_ptr->flags[1], SIP_PAGE2_OUTGOING_CALL) ? "OUTGOING": "INCOMING", 09190 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 09191 09192 /* deadlock avoidance... */ 09193 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 09194 DEADLOCK_AVOIDANCE(&sip_pvt_ptr->lock); 09195 } 09196 break; 09197 } 09198 } 09199 ast_mutex_unlock(&iflock); 09200 if (option_debug > 3 && !sip_pvt_ptr) 09201 ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 09202 return sip_pvt_ptr; 09203 }
static const char * gettag | ( | const struct sip_request * | req, | |
const char * | header, | |||
char * | tagbuf, | |||
int | tagbufsize | |||
) | [static] |
Get tag from packet.
Definition at line 13604 of file chan_sip.c.
References ast_copy_string(), and get_header().
Referenced by find_call(), handle_request(), handle_request_subscribe(), and handle_response().
13605 { 13606 const char *thetag; 13607 13608 if (!tagbuf) 13609 return NULL; 13610 tagbuf[0] = '\0'; /* reset the buffer */ 13611 thetag = get_header(req, header); 13612 thetag = strcasestr(thetag, ";tag="); 13613 if (thetag) { 13614 thetag += 5; 13615 ast_copy_string(tagbuf, thetag, tagbufsize); 13616 return strsep(&tagbuf, ";"); 13617 } 13618 return NULL; 13619 }
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 16816 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().
16817 { 16818 int res = 1; 16819 16820 if (!strcasecmp(v->name, "trustrpid")) { 16821 ast_set_flag(&mask[0], SIP_TRUSTRPID); 16822 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 16823 } else if (!strcasecmp(v->name, "sendrpid")) { 16824 ast_set_flag(&mask[0], SIP_SENDRPID); 16825 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 16826 } else if (!strcasecmp(v->name, "g726nonstandard")) { 16827 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 16828 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 16829 } else if (!strcasecmp(v->name, "useclientcode")) { 16830 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 16831 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 16832 } else if (!strcasecmp(v->name, "dtmfmode")) { 16833 ast_set_flag(&mask[0], SIP_DTMF); 16834 ast_clear_flag(&flags[0], SIP_DTMF); 16835 if (!strcasecmp(v->value, "inband")) 16836 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 16837 else if (!strcasecmp(v->value, "rfc2833")) 16838 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 16839 else if (!strcasecmp(v->value, "info")) 16840 ast_set_flag(&flags[0], SIP_DTMF_INFO); 16841 else if (!strcasecmp(v->value, "auto")) 16842 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 16843 else { 16844 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 16845 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 16846 } 16847 } else if (!strcasecmp(v->name, "nat")) { 16848 ast_set_flag(&mask[0], SIP_NAT); 16849 ast_clear_flag(&flags[0], SIP_NAT); 16850 if (!strcasecmp(v->value, "never")) 16851 ast_set_flag(&flags[0], SIP_NAT_NEVER); 16852 else if (!strcasecmp(v->value, "route")) 16853 ast_set_flag(&flags[0], SIP_NAT_ROUTE); 16854 else if (ast_true(v->value)) 16855 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 16856 else 16857 ast_set_flag(&flags[0], SIP_NAT_RFC3581); 16858 } else if (!strcasecmp(v->name, "canreinvite")) { 16859 ast_set_flag(&mask[0], SIP_REINVITE); 16860 ast_clear_flag(&flags[0], SIP_REINVITE); 16861 if(ast_true(v->value)) { 16862 ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT); 16863 } else if (!ast_false(v->value)) { 16864 char buf[64]; 16865 char *word, *next = buf; 16866 16867 ast_copy_string(buf, v->value, sizeof(buf)); 16868 while ((word = strsep(&next, ","))) { 16869 if(!strcasecmp(word, "update")) { 16870 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 16871 } else if(!strcasecmp(word, "nonat")) { 16872 ast_set_flag(&flags[0], SIP_CAN_REINVITE); 16873 ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT); 16874 } else { 16875 ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno); 16876 } 16877 } 16878 } 16879 } else if (!strcasecmp(v->name, "insecure")) { 16880 ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16881 ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16882 set_insecure_flags(flags, v->value, v->lineno); 16883 } else if (!strcasecmp(v->name, "progressinband")) { 16884 ast_set_flag(&mask[0], SIP_PROG_INBAND); 16885 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 16886 if (ast_true(v->value)) 16887 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 16888 else if (strcasecmp(v->value, "never")) 16889 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 16890 } else if (!strcasecmp(v->name, "promiscredir")) { 16891 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 16892 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 16893 } else if (!strcasecmp(v->name, "videosupport")) { 16894 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 16895 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 16896 } else if (!strcasecmp(v->name, "allowoverlap")) { 16897 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 16898 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 16899 } else if (!strcasecmp(v->name, "allowsubscribe")) { 16900 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 16901 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 16902 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 16903 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 16904 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 16905 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 16906 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 16907 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 16908 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 16909 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 16910 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 16911 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 16912 #endif 16913 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 16914 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 16915 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 16916 } else if (!strcasecmp(v->name, "buggymwi")) { 16917 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 16918 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 16919 } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { 16920 ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); 16921 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); 16922 } else 16923 res = 0; 16924 16925 return res; 16926 }
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 13789 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().
13790 { 13791 struct ast_frame *f; 13792 int earlyreplace = 0; 13793 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 13794 struct ast_channel *c = p->owner; /* Our incoming call */ 13795 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 13796 struct ast_channel *targetcall; /* The bridge to the take-over target */ 13797 13798 /* Check if we're in ring state */ 13799 if (replacecall->_state == AST_STATE_RING) 13800 earlyreplace = 1; 13801 13802 /* Check if we have a bridge */ 13803 if (!(targetcall = ast_bridged_channel(replacecall))) { 13804 /* We have no bridge */ 13805 if (!earlyreplace) { 13806 if (option_debug > 1) 13807 ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 13808 oneleggedreplace = 1; 13809 } 13810 } 13811 if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING) 13812 ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n"); 13813 13814 if (option_debug > 3) { 13815 if (targetcall) 13816 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); 13817 else 13818 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 13819 } 13820 13821 if (ignore) { 13822 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 13823 /* We should answer something here. If we are here, the 13824 call we are replacing exists, so an accepted 13825 can't harm */ 13826 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13827 /* Do something more clever here */ 13828 ast_channel_unlock(c); 13829 ast_mutex_unlock(&p->refer->refer_call->lock); 13830 return 1; 13831 } 13832 if (!c) { 13833 /* What to do if no channel ??? */ 13834 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 13835 transmit_response_reliable(p, "503 Service Unavailable", req); 13836 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 13837 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13838 ast_mutex_unlock(&p->refer->refer_call->lock); 13839 return 1; 13840 } 13841 append_history(p, "Xfer", "INVITE/Replace received"); 13842 /* We have three channels to play with 13843 channel c: New incoming call 13844 targetcall: Call from PBX to target 13845 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 13846 replacecall: The owner of the previous 13847 We need to masq C into refer_call to connect to 13848 targetcall; 13849 If we are talking to internal audio stream, target call is null. 13850 */ 13851 13852 /* Fake call progress */ 13853 transmit_response(p, "100 Trying", req); 13854 ast_setstate(c, AST_STATE_RING); 13855 13856 /* Masquerade the new call into the referred call to connect to target call 13857 Targetcall is not touched by the masq */ 13858 13859 /* Answer the incoming call and set channel to UP state */ 13860 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13861 13862 ast_setstate(c, AST_STATE_UP); 13863 13864 /* Stop music on hold and other generators */ 13865 ast_quiet_chan(replacecall); 13866 ast_quiet_chan(targetcall); 13867 if (option_debug > 3) 13868 ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 13869 /* Unlock clone, but not original (replacecall) */ 13870 if (!oneleggedreplace) 13871 ast_channel_unlock(c); 13872 13873 /* Unlock PVT */ 13874 ast_mutex_unlock(&p->refer->refer_call->lock); 13875 13876 /* Make sure that the masq does not free our PVT for the old call */ 13877 if (! earlyreplace && ! oneleggedreplace ) 13878 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 13879 13880 /* Prepare the masquerade - if this does not happen, we will be gone */ 13881 if(ast_channel_masquerade(replacecall, c)) 13882 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 13883 else if (option_debug > 3) 13884 ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 13885 13886 /* The masquerade will happen as soon as someone reads a frame from the channel */ 13887 13888 /* C should now be in place of replacecall */ 13889 /* ast_read needs to lock channel */ 13890 ast_channel_unlock(c); 13891 13892 if (earlyreplace || oneleggedreplace ) { 13893 /* Force the masq to happen */ 13894 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13895 ast_frfree(f); 13896 f = NULL; 13897 if (option_debug > 3) 13898 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from RING channel!\n"); 13899 } else { 13900 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from RING channel \n"); 13901 } 13902 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13903 if (!oneleggedreplace) 13904 ast_channel_unlock(replacecall); 13905 } else { /* Bridged call, UP channel */ 13906 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13907 /* Masq ok */ 13908 ast_frfree(f); 13909 f = NULL; 13910 if (option_debug > 2) 13911 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from channel! Masq done.\n"); 13912 } else { 13913 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from channel. Transfer failed\n"); 13914 } 13915 ast_channel_unlock(replacecall); 13916 } 13917 ast_mutex_unlock(&p->refer->refer_call->lock); 13918 13919 ast_setstate(c, AST_STATE_DOWN); 13920 if (option_debug > 3) { 13921 struct ast_channel *test; 13922 ast_log(LOG_DEBUG, "After transfer:----------------------------\n"); 13923 ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 13924 if (replacecall) 13925 ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 13926 if (p->owner) { 13927 ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 13928 test = ast_bridged_channel(p->owner); 13929 if (test) 13930 ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 13931 else 13932 ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n"); 13933 } else 13934 ast_log(LOG_DEBUG, " -- No channel yet \n"); 13935 ast_log(LOG_DEBUG, "End After transfer:----------------------------\n"); 13936 } 13937 13938 ast_channel_unlock(p->owner); /* Unlock new owner */ 13939 if (!oneleggedreplace) 13940 ast_mutex_unlock(&p->lock); /* Unlock SIP structure */ 13941 13942 /* The call should be down with no ast_channel, so hang it up */ 13943 c->tech_pvt = NULL; 13944 ast_hangup(c); 13945 return 0; 13946 }
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 15763 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.
15764 { 15765 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 15766 relatively static */ 15767 const char *cmd; 15768 const char *cseq; 15769 const char *useragent; 15770 int seqno; 15771 int len; 15772 int ignore = FALSE; 15773 int respid; 15774 int res = 0; 15775 int debug = sip_debug_test_pvt(p); 15776 char *e; 15777 int error = 0; 15778 15779 /* Get Method and Cseq */ 15780 cseq = get_header(req, "Cseq"); 15781 cmd = req->header[0]; 15782 15783 /* Must have Cseq */ 15784 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 15785 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 15786 error = 1; 15787 } 15788 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 15789 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 15790 error = 1; 15791 } 15792 if (error) { 15793 if (!p->initreq.headers) /* New call */ 15794 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 15795 return -1; 15796 } 15797 /* Get the command XXX */ 15798 15799 cmd = req->rlPart1; 15800 e = req->rlPart2; 15801 15802 /* Save useragent of the client */ 15803 useragent = get_header(req, "User-Agent"); 15804 if (!ast_strlen_zero(useragent)) 15805 ast_string_field_set(p, useragent, useragent); 15806 15807 /* Find out SIP method for incoming request */ 15808 if (req->method == SIP_RESPONSE) { /* Response to our request */ 15809 /* Response to our request -- Do some sanity checks */ 15810 if (!p->initreq.headers) { 15811 if (option_debug) 15812 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 15813 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15814 return 0; 15815 } else if (p->ocseq && (p->ocseq < seqno) && (seqno != p->lastnoninvite)) { 15816 if (option_debug) 15817 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 15818 return -1; 15819 } else if (p->ocseq && (p->ocseq != seqno) && (seqno != p->lastnoninvite)) { 15820 /* ignore means "don't do anything with it" but still have to 15821 respond appropriately */ 15822 ignore = TRUE; 15823 ast_set_flag(req, SIP_PKT_IGNORE); 15824 ast_set_flag(req, SIP_PKT_IGNORE_RESP); 15825 append_history(p, "Ignore", "Ignoring this retransmit\n"); 15826 } else if (e) { 15827 e = ast_skip_blanks(e); 15828 if (sscanf(e, "%d %n", &respid, &len) != 1) { 15829 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 15830 } else { 15831 if (respid <= 0) { 15832 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 15833 return 0; 15834 } 15835 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 15836 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 15837 extract_uri(p, req); 15838 handle_response(p, respid, e + len, req, ignore, seqno); 15839 } 15840 } 15841 return 0; 15842 } 15843 15844 /* New SIP request coming in 15845 (could be new request in existing SIP dialog as well...) 15846 */ 15847 15848 p->method = req->method; /* Find out which SIP method they are using */ 15849 if (option_debug > 3) 15850 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 15851 15852 if (p->icseq && (p->icseq > seqno) ) { 15853 if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) { 15854 if (option_debug > 2) 15855 ast_log(LOG_DEBUG, "Got CANCEL or ACK on INVITE with transactions in between.\n"); 15856 } else { 15857 if (option_debug) 15858 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 15859 if (req->method != SIP_ACK) 15860 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 15861 return -1; 15862 } 15863 } else if (p->icseq && 15864 p->icseq == seqno && 15865 req->method != SIP_ACK && 15866 (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) { 15867 /* ignore means "don't do anything with it" but still have to 15868 respond appropriately. We do this if we receive a repeat of 15869 the last sequence number */ 15870 ignore = 2; 15871 ast_set_flag(req, SIP_PKT_IGNORE); 15872 ast_set_flag(req, SIP_PKT_IGNORE_REQ); 15873 if (option_debug > 2) 15874 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 15875 } 15876 15877 if (seqno >= p->icseq) 15878 /* Next should follow monotonically (but not necessarily 15879 incrementally -- thanks again to the genius authors of SIP -- 15880 increasing */ 15881 p->icseq = seqno; 15882 15883 /* Find their tag if we haven't got it */ 15884 if (ast_strlen_zero(p->theirtag)) { 15885 char tag[128]; 15886 15887 gettag(req, "From", tag, sizeof(tag)); 15888 ast_string_field_set(p, theirtag, tag); 15889 } 15890 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 15891 15892 if (pedanticsipchecking) { 15893 /* If this is a request packet without a from tag, it's not 15894 correct according to RFC 3261 */ 15895 /* Check if this a new request in a new dialog with a totag already attached to it, 15896 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 15897 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 15898 /* If this is a first request and it got a to-tag, it is not for us */ 15899 if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) { 15900 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 15901 /* Will cease to exist after ACK */ 15902 } else if (req->method != SIP_ACK) { 15903 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 15904 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15905 } 15906 return res; 15907 } 15908 } 15909 15910 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 15911 transmit_response(p, "400 Bad request", req); 15912 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15913 return -1; 15914 } 15915 15916 /* Handle various incoming SIP methods in requests */ 15917 switch (p->method) { 15918 case SIP_OPTIONS: 15919 res = handle_request_options(p, req); 15920 break; 15921 case SIP_INVITE: 15922 res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock); 15923 break; 15924 case SIP_REFER: 15925 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 15926 break; 15927 case SIP_CANCEL: 15928 res = handle_request_cancel(p, req); 15929 break; 15930 case SIP_BYE: 15931 res = handle_request_bye(p, req); 15932 break; 15933 case SIP_MESSAGE: 15934 res = handle_request_message(p, req); 15935 break; 15936 case SIP_SUBSCRIBE: 15937 res = handle_request_subscribe(p, req, sin, seqno, e); 15938 break; 15939 case SIP_REGISTER: 15940 res = handle_request_register(p, req, sin, e); 15941 break; 15942 case SIP_INFO: 15943 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15944 ast_verbose("Receiving INFO!\n"); 15945 if (!ignore) 15946 handle_request_info(p, req); 15947 else /* if ignoring, transmit response */ 15948 transmit_response(p, "200 OK", req); 15949 break; 15950 case SIP_NOTIFY: 15951 res = handle_request_notify(p, req, sin, seqno, e); 15952 break; 15953 case SIP_ACK: 15954 /* Make sure we don't ignore this */ 15955 if (seqno == p->pendinginvite) { 15956 p->invitestate = INV_TERMINATED; 15957 p->pendinginvite = 0; 15958 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 15959 if (find_sdp(req)) { 15960 if (process_sdp(p, req)) 15961 return -1; 15962 } 15963 check_pendings(p); 15964 } 15965 /* Got an ACK that we did not match. Ignore silently */ 15966 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 15967 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15968 break; 15969 default: 15970 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 15971 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 15972 cmd, ast_inet_ntoa(p->sa.sin_addr)); 15973 /* If this is some new method, and we don't have a call, destroy it now */ 15974 if (!p->initreq.headers) 15975 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15976 break; 15977 } 15978 return res; 15979 }
static int handle_request_bye | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming BYE request.
Definition at line 15324 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().
15325 { 15326 struct ast_channel *c=NULL; 15327 int res; 15328 struct ast_channel *bridged_to; 15329 15330 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 15331 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 15332 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 15333 15334 __sip_pretend_ack(p); 15335 15336 p->invitestate = INV_TERMINATED; 15337 15338 copy_request(&p->initreq, req); 15339 check_via(p, req); 15340 sip_alreadygone(p); 15341 15342 /* Get RTCP quality before end of call */ 15343 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { 15344 char *audioqos, *videoqos; 15345 if (p->rtp) { 15346 audioqos = ast_rtp_get_quality(p->rtp, NULL); 15347 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 15348 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 15349 if (p->owner) 15350 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 15351 } 15352 if (p->vrtp) { 15353 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 15354 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 15355 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 15356 if (p->owner) 15357 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 15358 } 15359 } 15360 15361 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 15362 15363 if (!ast_strlen_zero(get_header(req, "Also"))) { 15364 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 15365 ast_inet_ntoa(p->recv.sin_addr)); 15366 if (ast_strlen_zero(p->context)) 15367 ast_string_field_set(p, context, default_context); 15368 res = get_also_info(p, req); 15369 if (!res) { 15370 c = p->owner; 15371 if (c) { 15372 bridged_to = ast_bridged_channel(c); 15373 if (bridged_to) { 15374 /* Don't actually hangup here... */ 15375 ast_queue_control(c, AST_CONTROL_UNHOLD); 15376 ast_async_goto(bridged_to, p->context, p->refer->refer_to,1); 15377 } else 15378 ast_queue_hangup(p->owner); 15379 } 15380 } else { 15381 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 15382 if (p->owner) 15383 ast_queue_hangup(p->owner); 15384 } 15385 } else if (p->owner) { 15386 ast_queue_hangup(p->owner); 15387 if (option_debug > 2) 15388 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n"); 15389 } else { 15390 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15391 if (option_debug > 2) 15392 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n"); 15393 } 15394 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15395 transmit_response(p, "200 OK", req); 15396 15397 return 1; 15398 }
static int handle_request_cancel | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming CANCEL request.
Definition at line 15218 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().
15219 { 15220 15221 check_via(p, req); 15222 sip_alreadygone(p); 15223 15224 /* At this point, we could have cancelled the invite at the same time 15225 as the other side sends a CANCEL. Our final reply with error code 15226 might not have been received by the other side before the CANCEL 15227 was sent, so let's just give up retransmissions and waiting for 15228 ACK on our error code. The call is hanging up any way. */ 15229 if (p->invitestate == INV_TERMINATED) 15230 __sip_pretend_ack(p); 15231 else 15232 p->invitestate = INV_CANCELLED; 15233 15234 if (p->owner && p->owner->_state == AST_STATE_UP) { 15235 /* This call is up, cancel is ignored, we need a bye */ 15236 transmit_response(p, "200 OK", req); 15237 if (option_debug) 15238 ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n"); 15239 return 0; 15240 } 15241 15242 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 15243 update_call_counter(p, DEC_CALL_LIMIT); 15244 15245 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 15246 if (p->owner) 15247 ast_queue_hangup(p->owner); 15248 else 15249 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15250 if (p->initreq.len > 0) { 15251 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 15252 transmit_response(p, "200 OK", req); 15253 return 1; 15254 } else { 15255 transmit_response(p, "481 Call Leg Does Not Exist", req); 15256 return 0; 15257 } 15258 }
static void handle_request_info | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP INFO Message.
Definition at line 11370 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().
11371 { 11372 char buf[1024]; 11373 unsigned int event; 11374 const char *c = get_header(req, "Content-Type"); 11375 11376 /* Need to check the media/type */ 11377 if (!strcasecmp(c, "application/dtmf-relay") || 11378 !strcasecmp(c, "application/DTMF") || 11379 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 11380 unsigned int duration = 0; 11381 11382 /* Try getting the "signal=" part */ 11383 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 11384 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 11385 transmit_response(p, "200 OK", req); /* Should return error */ 11386 return; 11387 } else { 11388 ast_copy_string(buf, c, sizeof(buf)); 11389 } 11390 11391 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 11392 duration = atoi(c); 11393 if (!duration) 11394 duration = 100; /* 100 ms */ 11395 11396 if (!p->owner) { /* not a PBX call */ 11397 transmit_response(p, "481 Call leg/transaction does not exist", req); 11398 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11399 return; 11400 } 11401 11402 if (ast_strlen_zero(buf)) { 11403 transmit_response(p, "200 OK", req); 11404 return; 11405 } 11406 11407 if (buf[0] == '*') 11408 event = 10; 11409 else if (buf[0] == '#') 11410 event = 11; 11411 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 11412 event = 12 + buf[0] - 'A'; 11413 else 11414 event = atoi(buf); 11415 if (event == 16) { 11416 /* send a FLASH event */ 11417 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 11418 ast_queue_frame(p->owner, &f); 11419 if (sipdebug) 11420 ast_verbose("* DTMF-relay event received: FLASH\n"); 11421 } else { 11422 /* send a DTMF event */ 11423 struct ast_frame f = { AST_FRAME_DTMF, }; 11424 if (event < 10) { 11425 f.subclass = '0' + event; 11426 } else if (event < 11) { 11427 f.subclass = '*'; 11428 } else if (event < 12) { 11429 f.subclass = '#'; 11430 } else if (event < 16) { 11431 f.subclass = 'A' + (event - 12); 11432 } 11433 f.len = duration; 11434 ast_queue_frame(p->owner, &f); 11435 if (sipdebug) 11436 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 11437 } 11438 transmit_response(p, "200 OK", req); 11439 return; 11440 } else if (!strcasecmp(c, "application/media_control+xml")) { 11441 /* Eh, we'll just assume it's a fast picture update for now */ 11442 if (p->owner) 11443 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 11444 transmit_response(p, "200 OK", req); 11445 return; 11446 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 11447 /* Client code (from SNOM phone) */ 11448 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 11449 if (p->owner && p->owner->cdr) 11450 ast_cdr_setuserfield(p->owner, c); 11451 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 11452 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 11453 transmit_response(p, "200 OK", req); 11454 } else { 11455 transmit_response(p, "403 Unauthorized", req); 11456 } 11457 return; 11458 } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) { 11459 /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */ 11460 transmit_response(p, "200 OK", req); 11461 return; 11462 } 11463 11464 /* Other type of INFO message, not really understood by Asterisk */ 11465 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 11466 11467 /* Nothing in the header is interesting, now check if content-length is 0 */ 11468 if (!strcasecmp(get_header(req, "Content-Length"), "0")) { 11469 transmit_response(p, "200 OK", req); 11470 return; 11471 } /* else ... there issomething in the message body, do something with it if you need to */ 11472 11473 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 11474 transmit_response(p, "415 Unsupported media type", req); 11475 return; 11476 }
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 14214 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_BUSY, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_pickup_call(), ast_pickup_ext(), ast_queue_control(), ast_queue_frame(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_set_flag, ast_setstate(), ast_skip_blanks(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), build_route(), ast_channel::call_forward, sip_pvt::callid, sip_pvt::capability, change_hold_state(), check_user(), check_via(), context, sip_pvt::context, copy_request(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, exten, sip_pvt::exten, extract_uri(), FALSE, find_sdp(), sip_pvt::flags, get_destination(), get_header(), get_rdnis(), get_sip_pvt_byid_locked(), handle_invite_replaces(), ast_channel::hangupcause, sip_request::headers, INC_CALL_LIMIT, sip_pvt::initreq, INV_COMPLETED, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::jointcapability, sip_pvt::lastinvite, sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, make_our_tag(), ast_channel::name, option_debug, sip_pvt::owner, parse_ok_contact(), parse_sip_options(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_request::rlPart2, sip_pvt::rtp, S_OR, sip_alreadygone(), sip_cancel_destroy(), SIP_DTMF, SIP_DTMF_RFC2833, sip_handle_t38_reinvite(), SIP_INVITE, sip_new(), SIP_NO_HISTORY, SIP_OPT_REPLACES, SIP_OUTGOING, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PKT_IGNORE, sip_refer_allocate(), sip_scheddestroy(), sip_tech, sip_tech_info, sip_uri_cmp(), sipdebug, sip_pvt::sipoptions, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_PEER_REINVITE, sip_pvt::tag, ast_channel::tech, ast_channel::tech_pvt, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, sip_pvt::udptl, update_call_counter(), sip_pvt::username, XMIT_CRITICAL, XMIT_RELIABLE, and XMIT_UNRELIABLE.
Referenced by handle_request().
14215 { 14216 int res = 1; 14217 int gotdest; 14218 const char *p_replaces; 14219 char *replace_id = NULL; 14220 const char *required; 14221 unsigned int required_profile = 0; 14222 struct ast_channel *c = NULL; /* New channel */ 14223 int reinvite = 0; 14224 14225 /* Find out what they support */ 14226 if (!p->sipoptions) { 14227 const char *supported = get_header(req, "Supported"); 14228 if (!ast_strlen_zero(supported)) 14229 parse_sip_options(p, supported); 14230 } 14231 14232 /* Find out what they require */ 14233 required = get_header(req, "Require"); 14234 if (!ast_strlen_zero(required)) { 14235 required_profile = parse_sip_options(NULL, required); 14236 if (required_profile && required_profile != SIP_OPT_REPLACES) { 14237 /* At this point we only support REPLACES */ 14238 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 14239 ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required); 14240 p->invitestate = INV_COMPLETED; 14241 if (!p->lastinvite) 14242 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14243 return -1; 14244 } 14245 } 14246 14247 /* Check if this is a loop */ 14248 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 14249 /* This is a call to ourself. Send ourselves an error code and stop 14250 processing immediately, as SIP really has no good mechanism for 14251 being able to call yourself */ 14252 /* If pedantic is on, we need to check the tags. If they're different, this is 14253 in fact a forked call through a SIP proxy somewhere. */ 14254 int different; 14255 if (pedanticsipchecking) 14256 different = sip_uri_cmp(p->initreq.rlPart2, req->rlPart2); 14257 else 14258 different = strcmp(p->initreq.rlPart2, req->rlPart2); 14259 if (!different) { 14260 transmit_response(p, "482 Loop Detected", req); 14261 p->invitestate = INV_COMPLETED; 14262 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14263 return 0; 14264 } else { 14265 /* This is a spiral. What we need to do is to just change the outgoing INVITE 14266 * so that it now routes to the new Request URI. Since we created the INVITE ourselves 14267 * that should be all we need to do. 14268 */ 14269 char *uri = ast_strdupa(req->rlPart2); 14270 char *at = strchr(uri, '@'); 14271 char *peerorhost; 14272 if (option_debug > 2) { 14273 ast_log(LOG_DEBUG, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", p->initreq.rlPart2, req->rlPart2); 14274 } 14275 if (at) { 14276 *at = '\0'; 14277 } 14278 /* Parse out "sip:" */ 14279 if ((peerorhost = strchr(uri, ':'))) { 14280 *peerorhost++ = '\0'; 14281 } 14282 ast_string_field_free(p, theirtag); 14283 /* Treat this as if there were a call forward instead... 14284 */ 14285 ast_string_field_set(p->owner, call_forward, peerorhost); 14286 ast_queue_control(p->owner, AST_CONTROL_BUSY); 14287 return 0; 14288 } 14289 } 14290 14291 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) { 14292 /* We already have a pending invite. Sorry. You are on hold. */ 14293 transmit_response_reliable(p, "491 Request Pending", req); 14294 if (option_debug) 14295 ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 14296 /* Don't destroy dialog here */ 14297 return 0; 14298 } 14299 14300 p_replaces = get_header(req, "Replaces"); 14301 if (!ast_strlen_zero(p_replaces)) { 14302 /* We have a replaces header */ 14303 char *ptr; 14304 char *fromtag = NULL; 14305 char *totag = NULL; 14306 char *start, *to; 14307 int error = 0; 14308 14309 if (p->owner) { 14310 if (option_debug > 2) 14311 ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 14312 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 14313 /* Do not destroy existing call */ 14314 return -1; 14315 } 14316 14317 if (sipdebug && option_debug > 2) 14318 ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 14319 /* Create a buffer we can manipulate */ 14320 replace_id = ast_strdupa(p_replaces); 14321 ast_uri_decode(replace_id); 14322 14323 if (!p->refer && !sip_refer_allocate(p)) { 14324 transmit_response_reliable(p, "500 Server Internal Error", req); 14325 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 14326 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14327 p->invitestate = INV_COMPLETED; 14328 return -1; 14329 } 14330 14331 /* Todo: (When we find phones that support this) 14332 if the replaces header contains ";early-only" 14333 we can only replace the call in early 14334 stage, not after it's up. 14335 14336 If it's not in early mode, 486 Busy. 14337 */ 14338 14339 /* Skip leading whitespace */ 14340 replace_id = ast_skip_blanks(replace_id); 14341 14342 start = replace_id; 14343 while ( (ptr = strsep(&start, ";")) ) { 14344 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 14345 if ( (to = strcasestr(ptr, "to-tag=") ) ) 14346 totag = to + 7; /* skip the keyword */ 14347 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 14348 fromtag = to + 9; /* skip the keyword */ 14349 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 14350 } 14351 } 14352 14353 if (sipdebug && option_debug > 3) 14354 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>"); 14355 14356 14357 /* Try to find call that we are replacing 14358 If we have a Replaces header, we need to cancel that call if we succeed with this call 14359 */ 14360 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 14361 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 14362 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req); 14363 error = 1; 14364 } 14365 14366 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 14367 14368 /* The matched call is the call from the transferer to Asterisk . 14369 We want to bridge the bridged part of the call to the 14370 incoming invite, thus taking over the refered call */ 14371 14372 if (p->refer->refer_call == p) { 14373 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 14374 p->refer->refer_call = NULL; 14375 transmit_response_reliable(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 14376 error = 1; 14377 } 14378 14379 if (!error && !p->refer->refer_call->owner) { 14380 /* Oops, someting wrong anyway, no owner, no call */ 14381 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 14382 /* Check for better return code */ 14383 transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req); 14384 error = 1; 14385 } 14386 14387 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 ) { 14388 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 14389 transmit_response_reliable(p, "603 Declined (Replaces)", req); 14390 error = 1; 14391 } 14392 14393 if (error) { /* Give up this dialog */ 14394 append_history(p, "Xfer", "INVITE/Replace Failed."); 14395 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14396 ast_mutex_unlock(&p->lock); 14397 if (p->refer->refer_call) { 14398 ast_mutex_unlock(&p->refer->refer_call->lock); 14399 if (p->refer->refer_call->owner) { 14400 ast_channel_unlock(p->refer->refer_call->owner); 14401 } 14402 } 14403 p->invitestate = INV_COMPLETED; 14404 return -1; 14405 } 14406 } 14407 14408 14409 /* Check if this is an INVITE that sets up a new dialog or 14410 a re-invite in an existing dialog */ 14411 14412 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14413 int newcall = (p->initreq.headers ? TRUE : FALSE); 14414 14415 if (sip_cancel_destroy(p)) 14416 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 14417 /* This also counts as a pending invite */ 14418 p->pendinginvite = seqno; 14419 check_via(p, req); 14420 14421 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 14422 if (!p->owner) { /* Not a re-invite */ 14423 if (debug) 14424 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 14425 if (newcall) 14426 append_history(p, "Invite", "New call: %s", p->callid); 14427 parse_ok_contact(p, req); 14428 } else { /* Re-invite on existing call */ 14429 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 14430 /* Handle SDP here if we already have an owner */ 14431 if (find_sdp(req)) { 14432 if (process_sdp(p, req)) { 14433 transmit_response_reliable(p, "488 Not acceptable here", req); 14434 if (!p->lastinvite) 14435 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14436 return -1; 14437 } 14438 } else { 14439 p->jointcapability = p->capability; 14440 if (option_debug > 2) 14441 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 14442 /* Some devices signal they want to be put off hold by sending a re-invite 14443 *without* an SDP, which is supposed to mean "Go back to your state" 14444 and since they put os on remote hold, we go back to off hold */ 14445 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 14446 change_hold_state(p, req, FALSE, 0); 14447 } 14448 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */ 14449 append_history(p, "ReInv", "Re-invite received"); 14450 } 14451 } else if (debug) 14452 ast_verbose("Ignoring this INVITE request\n"); 14453 14454 14455 if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) { 14456 /* This is a new invite */ 14457 /* Handle authentication if this is our first invite */ 14458 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 14459 if (res == AUTH_CHALLENGE_SENT) { 14460 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 14461 return 0; 14462 } 14463 if (res < 0) { /* Something failed in authentication */ 14464 if (res == AUTH_FAKE_AUTH) { 14465 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 14466 transmit_fake_auth_response(p, req, 1); 14467 } else { 14468 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 14469 transmit_response_reliable(p, "403 Forbidden", req); 14470 } 14471 p->invitestate = INV_COMPLETED; 14472 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14473 ast_string_field_free(p, theirtag); 14474 return 0; 14475 } 14476 14477 /* We have a succesful authentication, process the SDP portion if there is one */ 14478 if (find_sdp(req)) { 14479 if (process_sdp(p, req)) { 14480 /* Unacceptable codecs */ 14481 transmit_response_reliable(p, "488 Not acceptable here", req); 14482 p->invitestate = INV_COMPLETED; 14483 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14484 if (option_debug) 14485 ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); 14486 return -1; 14487 } 14488 } else { /* No SDP in invite, call control session */ 14489 p->jointcapability = p->capability; 14490 if (option_debug > 1) 14491 ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n"); 14492 } 14493 14494 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 14495 /* This seems redundant ... see !p-owner above */ 14496 if (p->owner) 14497 ast_queue_frame(p->owner, &ast_null_frame); 14498 14499 14500 /* Initialize the context if it hasn't been already */ 14501 if (ast_strlen_zero(p->context)) 14502 ast_string_field_set(p, context, default_context); 14503 14504 14505 /* Check number of concurrent calls -vs- incoming limit HERE */ 14506 if (option_debug) 14507 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 14508 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 14509 if (res < 0) { 14510 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 14511 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 14512 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14513 p->invitestate = INV_COMPLETED; 14514 } 14515 return 0; 14516 } 14517 gotdest = get_destination(p, NULL); /* Get destination right away */ 14518 get_rdnis(p, NULL); /* Get redirect information */ 14519 extract_uri(p, req); /* Get the Contact URI */ 14520 build_contact(p); /* Build our contact header */ 14521 14522 if (p->rtp) { 14523 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 14524 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 14525 } 14526 14527 if (!replace_id && gotdest) { /* No matching extension found */ 14528 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 14529 transmit_response_reliable(p, "484 Address Incomplete", req); 14530 else { 14531 char *decoded_exten = ast_strdupa(p->exten); 14532 14533 transmit_response_reliable(p, "404 Not Found", req); 14534 ast_uri_decode(decoded_exten); 14535 ast_log(LOG_NOTICE, "Call from '%s' to extension" 14536 " '%s' rejected because extension not found.\n", 14537 S_OR(p->username, p->peername), decoded_exten); 14538 } 14539 p->invitestate = INV_COMPLETED; 14540 update_call_counter(p, DEC_CALL_LIMIT); 14541 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14542 return 0; 14543 } else { 14544 /* If no extension was specified, use the s one */ 14545 /* Basically for calling to IP/Host name only */ 14546 if (ast_strlen_zero(p->exten)) 14547 ast_string_field_set(p, exten, "s"); 14548 /* Initialize our tag */ 14549 14550 make_our_tag(p->tag, sizeof(p->tag)); 14551 /* First invitation - create the channel */ 14552 c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL)); 14553 *recount = 1; 14554 14555 /* Save Record-Route for any later requests we make on this dialogue */ 14556 build_route(p, req, 0); 14557 14558 if (c) { 14559 /* Pre-lock the call */ 14560 ast_channel_lock(c); 14561 } 14562 } 14563 } else { 14564 if (option_debug > 1 && sipdebug) { 14565 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 14566 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 14567 else 14568 ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 14569 } 14570 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 14571 reinvite = 1; 14572 c = p->owner; 14573 } 14574 14575 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 14576 p->lastinvite = seqno; 14577 14578 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 14579 /* Go and take over the target call */ 14580 if (sipdebug && option_debug > 3) 14581 ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid); 14582 return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin); 14583 } 14584 14585 14586 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 14587 switch(c->_state) { 14588 case AST_STATE_DOWN: 14589 if (option_debug > 1) 14590 ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name); 14591 transmit_response(p, "100 Trying", req); 14592 p->invitestate = INV_PROCEEDING; 14593 ast_setstate(c, AST_STATE_RING); 14594 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 14595 enum ast_pbx_result res; 14596 14597 res = ast_pbx_start(c); 14598 14599 switch(res) { 14600 case AST_PBX_FAILED: 14601 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 14602 p->invitestate = INV_COMPLETED; 14603 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14604 transmit_response(p, "503 Unavailable", req); 14605 else 14606 transmit_response_reliable(p, "503 Unavailable", req); 14607 break; 14608 case AST_PBX_CALL_LIMIT: 14609 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 14610 p->invitestate = INV_COMPLETED; 14611 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14612 transmit_response(p, "480 Temporarily Unavailable", req); 14613 else 14614 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 14615 break; 14616 case AST_PBX_SUCCESS: 14617 /* nothing to do */ 14618 break; 14619 } 14620 14621 if (res) { 14622 14623 /* Unlock locks so ast_hangup can do its magic */ 14624 ast_mutex_unlock(&c->lock); 14625 ast_mutex_unlock(&p->lock); 14626 ast_hangup(c); 14627 ast_mutex_lock(&p->lock); 14628 c = NULL; 14629 } 14630 } else { /* Pickup call in call group */ 14631 ast_channel_unlock(c); 14632 *nounlock = 1; 14633 if (ast_pickup_call(c)) { 14634 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 14635 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14636 transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */ 14637 else 14638 transmit_response_reliable(p, "503 Unavailable", req); 14639 sip_alreadygone(p); 14640 /* Unlock locks so ast_hangup can do its magic */ 14641 ast_mutex_unlock(&p->lock); 14642 c->hangupcause = AST_CAUSE_CALL_REJECTED; 14643 } else { 14644 ast_mutex_unlock(&p->lock); 14645 ast_setstate(c, AST_STATE_DOWN); 14646 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14647 } 14648 p->invitestate = INV_COMPLETED; 14649 ast_hangup(c); 14650 ast_mutex_lock(&p->lock); 14651 c = NULL; 14652 } 14653 break; 14654 case AST_STATE_RING: 14655 transmit_response(p, "100 Trying", req); 14656 p->invitestate = INV_PROCEEDING; 14657 break; 14658 case AST_STATE_RINGING: 14659 transmit_response(p, "180 Ringing", req); 14660 p->invitestate = INV_PROCEEDING; 14661 break; 14662 case AST_STATE_UP: 14663 if (option_debug > 1) 14664 ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); 14665 14666 transmit_response(p, "100 Trying", req); 14667 14668 if (p->t38.state == T38_PEER_REINVITE) { 14669 struct ast_channel *bridgepeer = NULL; 14670 struct sip_pvt *bridgepvt = NULL; 14671 14672 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14673 /* 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*/ 14674 /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */ 14675 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 14676 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14677 if (bridgepvt->t38.state == T38_DISABLED) { 14678 if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */ 14679 /* Send re-invite to the bridged channel */ 14680 sip_handle_t38_reinvite(bridgepeer, p, 1); 14681 } else { /* Something is wrong with peers udptl struct */ 14682 ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n"); 14683 ast_mutex_lock(&bridgepvt->lock); 14684 bridgepvt->t38.state = T38_DISABLED; 14685 ast_mutex_unlock(&bridgepvt->lock); 14686 if (option_debug > 1) 14687 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name); 14688 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14689 transmit_response(p, "488 Not acceptable here", req); 14690 else 14691 transmit_response_reliable(p, "488 Not acceptable here", req); 14692 14693 } 14694 } else { 14695 /* The other side is already setup for T.38 most likely so we need to acknowledge this too */ 14696 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 14697 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14698 p->t38.state = T38_ENABLED; 14699 if (option_debug) 14700 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14701 } 14702 } else { 14703 /* Other side is not a SIP channel */ 14704 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14705 transmit_response(p, "488 Not acceptable here", req); 14706 else 14707 transmit_response_reliable(p, "488 Not acceptable here", req); 14708 p->t38.state = T38_DISABLED; 14709 if (option_debug > 1) 14710 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14711 14712 if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */ 14713 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14714 } 14715 } else { 14716 /* we are not bridged in a call */ 14717 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 14718 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 14719 p->t38.state = T38_ENABLED; 14720 if (option_debug) 14721 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 14722 } 14723 } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */ 14724 int sendok = TRUE; 14725 14726 /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */ 14727 /* so handle it here (re-invite other party to RTP) */ 14728 struct ast_channel *bridgepeer = NULL; 14729 struct sip_pvt *bridgepvt = NULL; 14730 if ((bridgepeer = ast_bridged_channel(p->owner))) { 14731 if ((bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) && !ast_check_hangup(bridgepeer)) { 14732 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 14733 /* Does the bridged peer have T38 ? */ 14734 if (bridgepvt->t38.state == T38_ENABLED) { 14735 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 14736 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 14737 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14738 transmit_response(p, "488 Not Acceptable Here (unsupported)", req); 14739 else 14740 transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req); 14741 sendok = FALSE; 14742 } 14743 /* No bridged peer with T38 enabled*/ 14744 } 14745 } 14746 /* Respond to normal re-invite */ 14747 if (sendok) { 14748 /* If this is not a re-invite or something to ignore - it's critical */ 14749 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 14750 transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_CRITICAL))); 14751 } 14752 } 14753 p->invitestate = INV_TERMINATED; 14754 break; 14755 default: 14756 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 14757 transmit_response(p, "100 Trying", req); 14758 break; 14759 } 14760 } else { 14761 if (p && (p->autokillid == -1)) { 14762 const char *msg; 14763 14764 if (!p->jointcapability) 14765 msg = "488 Not Acceptable Here (codec error)"; 14766 else { 14767 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 14768 msg = "503 Unavailable"; 14769 } 14770 if (ast_test_flag(req, SIP_PKT_IGNORE)) 14771 transmit_response(p, msg, req); 14772 else 14773 transmit_response_reliable(p, msg, req); 14774 p->invitestate = INV_COMPLETED; 14775 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14776 } 14777 } 14778 return res; 14779 }
static int handle_request_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming MESSAGE request.
Definition at line 15401 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().
15402 { 15403 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 15404 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15405 ast_verbose("Receiving message!\n"); 15406 receive_message(p, req); 15407 } else 15408 transmit_response(p, "202 Accepted", req); 15409 return 1; 15410 }
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 13622 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().
13623 { 13624 /* This is mostly a skeleton for future improvements */ 13625 /* Mostly created to return proper answers on notifications on outbound REFER's */ 13626 int res = 0; 13627 const char *event = get_header(req, "Event"); 13628 char *eventid = NULL; 13629 char *sep; 13630 13631 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 13632 *sep++ = '\0'; 13633 eventid = sep; 13634 } 13635 13636 if (option_debug > 1 && sipdebug) 13637 ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event); 13638 13639 if (strcmp(event, "refer")) { 13640 /* We don't understand this event. */ 13641 /* Here's room to implement incoming voicemail notifications :-) */ 13642 transmit_response(p, "489 Bad event", req); 13643 res = -1; 13644 } else { 13645 /* Save nesting depth for now, since there might be other events we will 13646 support in the future */ 13647 13648 /* Handle REFER notifications */ 13649 13650 char buf[1024]; 13651 char *cmd, *code; 13652 int respcode; 13653 int success = TRUE; 13654 13655 /* EventID for each transfer... EventID is basically the REFER cseq 13656 13657 We are getting notifications on a call that we transfered 13658 We should hangup when we are getting a 200 OK in a sipfrag 13659 Check if we have an owner of this event */ 13660 13661 /* Check the content type */ 13662 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 13663 /* We need a sipfrag */ 13664 transmit_response(p, "400 Bad request", req); 13665 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13666 return -1; 13667 } 13668 13669 /* Get the text of the attachment */ 13670 if (get_msg_text(buf, sizeof(buf), req)) { 13671 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 13672 transmit_response(p, "400 Bad request", req); 13673 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13674 return -1; 13675 } 13676 13677 /* 13678 From the RFC... 13679 A minimal, but complete, implementation can respond with a single 13680 NOTIFY containing either the body: 13681 SIP/2.0 100 Trying 13682 13683 if the subscription is pending, the body: 13684 SIP/2.0 200 OK 13685 if the reference was successful, the body: 13686 SIP/2.0 503 Service Unavailable 13687 if the reference failed, or the body: 13688 SIP/2.0 603 Declined 13689 13690 if the REFER request was accepted before approval to follow the 13691 reference could be obtained and that approval was subsequently denied 13692 (see Section 2.4.7). 13693 13694 If there are several REFERs in the same dialog, we need to 13695 match the ID of the event header... 13696 */ 13697 if (option_debug > 2) 13698 ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 13699 cmd = ast_skip_blanks(buf); 13700 code = cmd; 13701 /* We are at SIP/2.0 */ 13702 while(*code && (*code > 32)) { /* Search white space */ 13703 code++; 13704 } 13705 *code++ = '\0'; 13706 code = ast_skip_blanks(code); 13707 sep = code; 13708 sep++; 13709 while(*sep && (*sep > 32)) { /* Search white space */ 13710 sep++; 13711 } 13712 *sep++ = '\0'; /* Response string */ 13713 respcode = atoi(code); 13714 switch (respcode) { 13715 case 100: /* Trying: */ 13716 case 101: /* dialog establishment */ 13717 /* Don't do anything yet */ 13718 break; 13719 case 183: /* Ringing: */ 13720 /* Don't do anything yet */ 13721 break; 13722 case 200: /* OK: The new call is up, hangup this call */ 13723 /* Hangup the call that we are replacing */ 13724 break; 13725 case 301: /* Moved permenantly */ 13726 case 302: /* Moved temporarily */ 13727 /* Do we get the header in the packet in this case? */ 13728 success = FALSE; 13729 break; 13730 case 503: /* Service Unavailable: The new call failed */ 13731 /* Cancel transfer, continue the call */ 13732 success = FALSE; 13733 break; 13734 case 603: /* Declined: Not accepted */ 13735 /* Cancel transfer, continue the current call */ 13736 success = FALSE; 13737 break; 13738 } 13739 if (!success) { 13740 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 13741 } 13742 13743 /* Confirm that we received this packet */ 13744 transmit_response(p, "200 OK", req); 13745 }; 13746 13747 if (!p->lastinvite) 13748 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13749 13750 return res; 13751 }
static int handle_request_options | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Handle incoming OPTIONS request.
Definition at line 13754 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().
13755 { 13756 int res; 13757 13758 13759 /* XXX Should we authenticate OPTIONS? XXX */ 13760 13761 if (p->lastinvite) { 13762 /* if this is a request in an active dialog, just confirm that the dialog exists. */ 13763 transmit_response_with_allow(p, "200 OK", req, 0); 13764 return 0; 13765 } 13766 13767 res = get_destination(p, req); 13768 build_contact(p); 13769 13770 if (ast_strlen_zero(p->context)) 13771 ast_string_field_set(p, context, default_context); 13772 13773 if (ast_shutting_down()) 13774 transmit_response_with_allow(p, "503 Unavailable", req, 0); 13775 else if (res < 0) 13776 transmit_response_with_allow(p, "404 Not Found", req, 0); 13777 else 13778 transmit_response_with_allow(p, "200 OK", req, 0); 13779 13780 /* Destroy if this OPTIONS was the opening request, but not if 13781 it's in the middle of a normal call flow. */ 13782 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13783 13784 return res; 13785 }
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 14947 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().
14948 { 14949 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 14950 /* Chan2: Call between asterisk and transferee */ 14951 14952 int res = 0; 14953 14954 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14955 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"); 14956 14957 if (!p->owner) { 14958 /* This is a REFER outside of an existing SIP dialog */ 14959 /* We can't handle that, so decline it */ 14960 if (option_debug > 2) 14961 ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 14962 transmit_response(p, "603 Declined (No dialog)", req); 14963 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14964 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 14965 sip_alreadygone(p); 14966 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14967 } 14968 return 0; 14969 } 14970 14971 14972 /* Check if transfer is allowed from this device */ 14973 if (p->allowtransfer == TRANSFER_CLOSED ) { 14974 /* Transfer not allowed, decline */ 14975 transmit_response(p, "603 Declined (policy)", req); 14976 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 14977 /* Do not destroy SIP session */ 14978 return 0; 14979 } 14980 14981 if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 14982 /* Already have a pending REFER */ 14983 transmit_response(p, "491 Request pending", req); 14984 append_history(p, "Xfer", "Refer failed. Request pending."); 14985 return 0; 14986 } 14987 14988 /* Allocate memory for call transfer data */ 14989 if (!p->refer && !sip_refer_allocate(p)) { 14990 transmit_response(p, "500 Internal Server Error", req); 14991 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 14992 return -3; 14993 } 14994 14995 res = get_refer_info(p, req); /* Extract headers */ 14996 14997 p->refer->status = REFER_SENT; 14998 14999 if (res != 0) { 15000 switch (res) { 15001 case -2: /* Syntax error */ 15002 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 15003 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 15004 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 15005 ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 15006 break; 15007 case -3: 15008 transmit_response(p, "603 Declined (Non sip: uri)", req); 15009 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 15010 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 15011 ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n"); 15012 break; 15013 default: 15014 /* Refer-to extension not found, fake a failed transfer */ 15015 transmit_response(p, "202 Accepted", req); 15016 append_history(p, "Xfer", "Refer failed. Bad extension."); 15017 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 15018 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15019 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 15020 ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 15021 break; 15022 } 15023 return 0; 15024 } 15025 if (ast_strlen_zero(p->context)) 15026 ast_string_field_set(p, context, default_context); 15027 15028 /* If we do not support SIP domains, all transfers are local */ 15029 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 15030 p->refer->localtransfer = 1; 15031 if (sipdebug && option_debug > 2) 15032 ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 15033 } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 15034 /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */ 15035 p->refer->localtransfer = 1; 15036 } else if (sipdebug && option_debug > 2) 15037 ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 15038 15039 /* Is this a repeat of a current request? Ignore it */ 15040 /* Don't know what else to do right now. */ 15041 if (ignore) 15042 return res; 15043 15044 /* If this is a blind transfer, we have the following 15045 channels to work with: 15046 - chan1, chan2: The current call between transferer and transferee (2 channels) 15047 - target_channel: A new call from the transferee to the target (1 channel) 15048 We need to stay tuned to what happens in order to be able 15049 to bring back the call to the transferer */ 15050 15051 /* If this is a attended transfer, we should have all call legs within reach: 15052 - chan1, chan2: The call between the transferer and transferee (2 channels) 15053 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 15054 We want to bridge chan2 with targetcall_pvt! 15055 15056 The replaces call id in the refer message points 15057 to the call leg between Asterisk and the transferer. 15058 So we need to connect the target and the transferee channel 15059 and hangup the two other channels silently 15060 15061 If the target is non-local, the call ID could be on a remote 15062 machine and we need to send an INVITE with replaces to the 15063 target. We basically handle this as a blind transfer 15064 and let the sip_call function catch that we need replaces 15065 header in the INVITE. 15066 */ 15067 15068 15069 /* Get the transferer's channel */ 15070 current.chan1 = p->owner; 15071 15072 /* Find the other part of the bridge (2) - transferee */ 15073 current.chan2 = ast_bridged_channel(current.chan1); 15074 15075 if (sipdebug && option_debug > 2) 15076 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>"); 15077 15078 if (!current.chan2 && !p->refer->attendedtransfer) { 15079 /* No bridged channel, propably IVR or echo or similar... */ 15080 /* Guess we should masquerade or something here */ 15081 /* Until we figure it out, refuse transfer of such calls */ 15082 if (sipdebug && option_debug > 2) 15083 ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n"); 15084 p->refer->status = REFER_FAILED; 15085 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 15086 transmit_response(p, "603 Declined", req); 15087 return -1; 15088 } 15089 15090 if (current.chan2) { 15091 if (sipdebug && option_debug > 3) 15092 ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 15093 15094 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 15095 } 15096 15097 ast_set_flag(&p->flags[0], SIP_GOTREFER); 15098 15099 /* Attended transfer: Find all call legs and bridge transferee with target*/ 15100 if (p->refer->attendedtransfer) { 15101 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 15102 return res; /* We're done with the transfer */ 15103 /* Fall through for remote transfers that we did not find locally */ 15104 if (sipdebug && option_debug > 3) 15105 ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 15106 /* Fallthrough if we can't find the call leg internally */ 15107 } 15108 15109 15110 /* Parking a call */ 15111 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 15112 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 15113 *nounlock = 1; 15114 ast_channel_unlock(current.chan1); 15115 copy_request(¤t.req, req); 15116 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15117 p->refer->status = REFER_200OK; 15118 append_history(p, "Xfer", "REFER to call parking."); 15119 if (sipdebug && option_debug > 3) 15120 ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 15121 sip_park(current.chan2, current.chan1, req, seqno); 15122 return res; 15123 } 15124 15125 /* Blind transfers and remote attended xfers */ 15126 transmit_response(p, "202 Accepted", req); 15127 15128 if (current.chan1 && current.chan2) { 15129 if (option_debug > 2) 15130 ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name); 15131 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 15132 } 15133 if (current.chan2) { 15134 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 15135 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 15136 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 15137 /* One for the new channel */ 15138 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 15139 /* Attended transfer to remote host, prepare headers for the INVITE */ 15140 if (p->refer->referred_by) 15141 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 15142 } 15143 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 15144 if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) { 15145 char tempheader[SIPBUFSIZE]; 15146 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 15147 p->refer->replaces_callid_totag ? ";to-tag=" : "", 15148 p->refer->replaces_callid_totag, 15149 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 15150 p->refer->replaces_callid_fromtag); 15151 if (current.chan2) 15152 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 15153 } 15154 /* Must release lock now, because it will not longer 15155 be accessible after the transfer! */ 15156 *nounlock = 1; 15157 ast_channel_unlock(current.chan1); 15158 15159 /* Connect the call */ 15160 15161 /* FAKE ringing if not attended transfer */ 15162 if (!p->refer->attendedtransfer) 15163 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 15164 15165 /* For blind transfer, this will lead to a new call */ 15166 /* For attended transfer to remote host, this will lead to 15167 a new SIP call with a replaces header, if the dial plan allows it 15168 */ 15169 if (!current.chan2) { 15170 /* We have no bridge, so we're talking with Asterisk somehow */ 15171 /* We need to masquerade this call */ 15172 /* What to do to fix this situation: 15173 * Set up the new call in a new channel 15174 * Let the new channel masq into this channel 15175 Please add that code here :-) 15176 */ 15177 p->refer->status = REFER_FAILED; 15178 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 15179 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15180 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 15181 return -1; 15182 } 15183 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 15184 15185 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 15186 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 15187 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 15188 15189 if (!res) { 15190 /* Success - we have a new channel */ 15191 if (option_debug > 2) 15192 ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 15193 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 15194 if (p->refer->localtransfer) 15195 p->refer->status = REFER_200OK; 15196 if (p->owner) 15197 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 15198 append_history(p, "Xfer", "Refer succeeded."); 15199 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15200 /* Do not hangup call, the other side do that when we say 200 OK */ 15201 /* We could possibly implement a timer here, auto congestion */ 15202 res = 0; 15203 } else { 15204 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 15205 if (option_debug > 2) 15206 ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 15207 append_history(p, "Xfer", "Refer failed."); 15208 /* Failure of some kind */ 15209 p->refer->status = REFER_FAILED; 15210 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 15211 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 15212 res = -1; 15213 } 15214 return res; 15215 }
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 15710 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().
15711 { 15712 enum check_auth_result res; 15713 15714 /* Use this as the basis */ 15715 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15716 ast_verbose("Using latest REGISTER request as basis request\n"); 15717 copy_request(&p->initreq, req); 15718 check_via(p, req); 15719 if ((res = register_verify(p, sin, req, e)) < 0) { 15720 const char *reason; 15721 15722 switch (res) { 15723 case AUTH_SECRET_FAILED: 15724 reason = "Wrong password"; 15725 break; 15726 case AUTH_USERNAME_MISMATCH: 15727 reason = "Username/auth name mismatch"; 15728 break; 15729 case AUTH_NOT_FOUND: 15730 reason = "No matching peer found"; 15731 break; 15732 case AUTH_UNKNOWN_DOMAIN: 15733 reason = "Not a local domain"; 15734 break; 15735 case AUTH_PEER_NOT_DYNAMIC: 15736 reason = "Peer is not supposed to register"; 15737 break; 15738 case AUTH_ACL_FAILED: 15739 reason = "Device does not match ACL"; 15740 break; 15741 default: 15742 reason = "Unknown failure"; 15743 break; 15744 } 15745 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 15746 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 15747 reason); 15748 append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason); 15749 } else 15750 append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To")); 15751 15752 if (res < 1) { 15753 /* Destroy the session, but keep us around for just a bit in case they don't 15754 get our 200 OK */ 15755 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 15756 } 15757 return res; 15758 }
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 15413 of file chan_sip.c.
References append_history, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_extension_state_del(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), sip_pvt::callid, cb_extensionstate(), check_user_full(), check_via(), sip_pvt::context, copy_request(), CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, sip_pvt::expiry, sip_pvt::exten, FALSE, sip_pvt::flags, get_destination(), get_header(), gettag(), sip_request::headers, iflist, iflock, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::laststate, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, sip_peer::mailbox, make_our_tag(), sip_request::method, sip_peer::mwipvt, sip_peer::name, sip_pvt::next, NONE, option_debug, parse_ok_contact(), PIDF_XML, sip_pvt::relatedpeer, sip_pvt::sa, sip_cancel_destroy(), sip_destroy(), sip_destroy_peer(), sip_methods, SIP_NEEDDESTROY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_scheddestroy(), sip_send_mwi_to_peer(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stateid, sip_pvt::subscribecontext, sip_pvt::subscribed, sip_pvt::subscribeuri, sip_pvt::tag, cfsip_methods::text, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_state_notify(), sip_pvt::useragent, sip_pvt::username, and XPIDF_XML.
Referenced by handle_request().
15414 { 15415 int gotdest; 15416 int res = 0; 15417 int firststate = AST_EXTENSION_REMOVED; 15418 struct sip_peer *authpeer = NULL; 15419 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 15420 const char *accept = get_header(req, "Accept"); 15421 int resubscribe = (p->subscribed != NONE); 15422 char *temp, *event; 15423 15424 if (p->initreq.headers) { 15425 /* We already have a dialog */ 15426 if (p->initreq.method != SIP_SUBSCRIBE) { 15427 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 15428 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 15429 transmit_response(p, "403 Forbidden (within dialog)", req); 15430 /* Do not destroy session, since we will break the call if we do */ 15431 if (option_debug) 15432 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); 15433 return 0; 15434 } else if (ast_test_flag(req, SIP_PKT_DEBUG)) { 15435 if (option_debug) { 15436 if (resubscribe) 15437 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 15438 else 15439 ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid); 15440 } 15441 } 15442 } 15443 15444 /* Check if we have a global disallow setting on subscriptions. 15445 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 15446 */ 15447 if (!global_allowsubscribe) { 15448 transmit_response(p, "403 Forbidden (policy)", req); 15449 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15450 return 0; 15451 } 15452 15453 if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */ 15454 const char *to = get_header(req, "To"); 15455 char totag[128]; 15456 15457 /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */ 15458 if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) { 15459 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15460 ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n"); 15461 transmit_response(p, "481 Subscription does not exist", req); 15462 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15463 return 0; 15464 } 15465 15466 /* Use this as the basis */ 15467 if (ast_test_flag(req, SIP_PKT_DEBUG)) 15468 ast_verbose("Creating new subscription\n"); 15469 15470 copy_request(&p->initreq, req); 15471 check_via(p, req); 15472 } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE)) 15473 ast_verbose("Ignoring this SUBSCRIBE request\n"); 15474 15475 /* Find parameters to Event: header value and remove them for now */ 15476 if (ast_strlen_zero(eventheader)) { 15477 transmit_response(p, "489 Bad Event", req); 15478 if (option_debug > 1) 15479 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n"); 15480 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15481 return 0; 15482 } 15483 15484 if ( (strchr(eventheader, ';'))) { 15485 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 15486 temp = strchr(event, ';'); 15487 *temp = '\0'; /* Remove any options for now */ 15488 /* We might need to use them later :-) */ 15489 } else 15490 event = (char *) eventheader; /* XXX is this legal ? */ 15491 15492 /* Handle authentication */ 15493 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 15494 /* if an authentication response was sent, we are done here */ 15495 if (res == AUTH_CHALLENGE_SENT) { 15496 if (authpeer) 15497 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15498 return 0; 15499 } 15500 if (res < 0) { 15501 if (res == AUTH_FAKE_AUTH) { 15502 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 15503 transmit_fake_auth_response(p, req, 1); 15504 } else { 15505 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 15506 transmit_response_reliable(p, "403 Forbidden", req); 15507 } 15508 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15509 if (authpeer) 15510 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15511 return 0; 15512 } 15513 15514 /* Check if this user/peer is allowed to subscribe at all */ 15515 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 15516 transmit_response(p, "403 Forbidden (policy)", req); 15517 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15518 if (authpeer) 15519 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15520 return 0; 15521 } 15522 15523 /* Get destination right away */ 15524 gotdest = get_destination(p, NULL); 15525 15526 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 15527 parse_ok_contact(p, req); 15528 15529 build_contact(p); 15530 if (gotdest) { 15531 transmit_response(p, "404 Not Found", req); 15532 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15533 if (authpeer) 15534 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15535 return 0; 15536 } 15537 15538 /* Initialize tag for new subscriptions */ 15539 if (ast_strlen_zero(p->tag)) 15540 make_our_tag(p->tag, sizeof(p->tag)); 15541 15542 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 15543 if (authpeer) /* No need for authpeer here */ 15544 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15545 15546 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 15547 /* Polycom phones only handle xpidf+xml, even if they say they can 15548 handle pidf+xml as well 15549 */ 15550 if (strstr(p->useragent, "Polycom")) { 15551 p->subscribed = XPIDF_XML; 15552 } else if (strstr(accept, "application/pidf+xml")) { 15553 p->subscribed = PIDF_XML; /* RFC 3863 format */ 15554 } else if (strstr(accept, "application/dialog-info+xml")) { 15555 p->subscribed = DIALOG_INFO_XML; 15556 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 15557 } else if (strstr(accept, "application/cpim-pidf+xml")) { 15558 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 15559 } else if (strstr(accept, "application/xpidf+xml")) { 15560 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 15561 } else if (ast_strlen_zero(accept)) { 15562 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 15563 transmit_response(p, "489 Bad Event", req); 15564 15565 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 15566 p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 15567 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15568 return 0; 15569 } 15570 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 15571 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 15572 } else { 15573 /* Can't find a format for events that we know about */ 15574 char mybuf[200]; 15575 snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept); 15576 transmit_response(p, mybuf, req); 15577 15578 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 15579 accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 15580 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15581 return 0; 15582 } 15583 } else if (!strcmp(event, "message-summary")) { 15584 if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) { 15585 /* Format requested that we do not support */ 15586 transmit_response(p, "406 Not Acceptable", req); 15587 if (option_debug > 1) 15588 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept); 15589 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15590 if (authpeer) /* No need for authpeer here */ 15591 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15592 return 0; 15593 } 15594 /* Looks like they actually want a mailbox status 15595 This version of Asterisk supports mailbox subscriptions 15596 The subscribed URI needs to exist in the dial plan 15597 In most devices, this is configurable to the voicemailmain extension you use 15598 */ 15599 if (!authpeer || ast_strlen_zero(authpeer->mailbox)) { 15600 transmit_response(p, "404 Not found (no mailbox)", req); 15601 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15602 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 15603 if (authpeer) /* No need for authpeer here */ 15604 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15605 return 0; 15606 } 15607 15608 p->subscribed = MWI_NOTIFICATION; 15609 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 15610 /* We only allow one subscription per peer */ 15611 sip_destroy(authpeer->mwipvt); 15612 authpeer->mwipvt = p; /* Link from peer to pvt */ 15613 p->relatedpeer = ASTOBJ_REF(authpeer); /* Link from pvt to peer */ 15614 } else { /* At this point, Asterisk does not understand the specified event */ 15615 transmit_response(p, "489 Bad Event", req); 15616 if (option_debug > 1) 15617 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 15618 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15619 if (authpeer) /* No need for authpeer here */ 15620 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 15621 return 0; 15622 } 15623 15624 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) { 15625 if (p->stateid > -1) 15626 ast_extension_state_del(p->stateid, cb_extensionstate); 15627 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 15628 } 15629 15630 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 15631 p->lastinvite = seqno; 15632 if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 15633 p->expiry = atoi(get_header(req, "Expires")); 15634 15635 /* check if the requested expiry-time is within the approved limits from sip.conf */ 15636 if (p->expiry > max_expiry) 15637 p->expiry = max_expiry; 15638 if (p->expiry < min_expiry && p->expiry > 0) 15639 p->expiry = min_expiry; 15640 15641 if (sipdebug || option_debug > 1) { 15642 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 15643 ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox); 15644 else 15645 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 15646 } 15647 if (p->autokillid > -1 && sip_cancel_destroy(p)) /* Remove subscription expiry for renewals */ 15648 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 15649 if (p->expiry > 0) 15650 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 15651 15652 if (p->subscribed == MWI_NOTIFICATION) { 15653 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15654 transmit_response(p, "200 OK", req); 15655 if (p->relatedpeer) { /* Send first notification */ 15656 ASTOBJ_WRLOCK(p->relatedpeer); 15657 sip_send_mwi_to_peer(p->relatedpeer); 15658 ASTOBJ_UNLOCK(p->relatedpeer); 15659 } 15660 } else { 15661 struct sip_pvt *p_old; 15662 15663 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 15664 15665 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)); 15666 transmit_response(p, "404 Not found", req); 15667 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15668 return 0; 15669 } 15670 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 15671 transmit_response(p, "200 OK", req); 15672 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 15673 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 15674 /* hide the 'complete' exten/context in the refer_to field for later display */ 15675 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 15676 15677 /* remove any old subscription from this peer for the same exten/context, 15678 as the peer has obviously forgotten about it and it's wasteful to wait 15679 for it to expire and send NOTIFY messages to the peer only to have them 15680 ignored (or generate errors) 15681 */ 15682 ast_mutex_lock(&iflock); 15683 for (p_old = iflist; p_old; p_old = p_old->next) { 15684 if (p_old == p) 15685 continue; 15686 if (p_old->initreq.method != SIP_SUBSCRIBE) 15687 continue; 15688 if (p_old->subscribed == NONE) 15689 continue; 15690 ast_mutex_lock(&p_old->lock); 15691 if (!strcmp(p_old->username, p->username)) { 15692 if (!strcmp(p_old->exten, p->exten) && 15693 !strcmp(p_old->context, p->context)) { 15694 ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY); 15695 ast_mutex_unlock(&p_old->lock); 15696 break; 15697 } 15698 } 15699 ast_mutex_unlock(&p_old->lock); 15700 } 15701 ast_mutex_unlock(&iflock); 15702 } 15703 if (!p->expiry) 15704 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 15705 } 15706 return 1; 15707 }
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 12902 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.
12903 { 12904 struct ast_channel *owner; 12905 int sipmethod; 12906 int res = 1; 12907 const char *c = get_header(req, "Cseq"); 12908 /* 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 */ 12909 char *c_copy = ast_strdupa(c); 12910 /* Skip the Cseq and its subsequent spaces */ 12911 const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy)); 12912 12913 if (!msg) 12914 msg = ""; 12915 12916 sipmethod = find_sip_method(msg); 12917 12918 owner = p->owner; 12919 if (owner) 12920 owner->hangupcause = hangup_sip2cause(resp); 12921 12922 /* Acknowledge whatever it is destined for */ 12923 if ((resp >= 100) && (resp <= 199)) 12924 __sip_semi_ack(p, seqno, 0, sipmethod); 12925 else 12926 __sip_ack(p, seqno, 0, sipmethod); 12927 12928 /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */ 12929 if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 12930 p->pendinginvite = 0; 12931 12932 /* Get their tag if we haven't already */ 12933 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 12934 char tag[128]; 12935 12936 gettag(req, "To", tag, sizeof(tag)); 12937 ast_string_field_set(p, theirtag, tag); 12938 } 12939 12940 /* RFC 3261 Section 15 specifies that if we receive a 408 or 481 12941 * in response to a BYE, then we should end the current dialog 12942 * and session. It is known that at least one phone manufacturer 12943 * potentially will send a 404 in response to a BYE, so we'll be 12944 * liberal in what we accept and end the dialog and session if we 12945 * receive any of those responses to a BYE. 12946 */ 12947 if ((resp == 404 || resp == 408 || resp == 481) && sipmethod == SIP_BYE) { 12948 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12949 return; 12950 } 12951 12952 if (p->relatedpeer && p->method == SIP_OPTIONS) { 12953 /* We don't really care what the response is, just that it replied back. 12954 Well, as long as it's not a 100 response... since we might 12955 need to hang around for something more "definitive" */ 12956 if (resp != 100) 12957 handle_response_peerpoke(p, resp, req); 12958 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12959 switch(resp) { 12960 case 100: /* 100 Trying */ 12961 case 101: /* 101 Dialog establishment */ 12962 if (sipmethod == SIP_INVITE) 12963 handle_response_invite(p, resp, rest, req, seqno); 12964 break; 12965 case 183: /* 183 Session Progress */ 12966 if (sipmethod == SIP_INVITE) 12967 handle_response_invite(p, resp, rest, req, seqno); 12968 break; 12969 case 180: /* 180 Ringing */ 12970 if (sipmethod == SIP_INVITE) 12971 handle_response_invite(p, resp, rest, req, seqno); 12972 break; 12973 case 182: /* 182 Queued */ 12974 if (sipmethod == SIP_INVITE) 12975 handle_response_invite(p, resp, rest, req, seqno); 12976 break; 12977 case 200: /* 200 OK */ 12978 p->authtries = 0; /* Reset authentication counter */ 12979 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 12980 /* We successfully transmitted a message 12981 or a video update request in INFO */ 12982 /* Nothing happens here - the message is inside a dialog */ 12983 } else if (sipmethod == SIP_INVITE) { 12984 handle_response_invite(p, resp, rest, req, seqno); 12985 } else if (sipmethod == SIP_NOTIFY) { 12986 /* They got the notify, this is the end */ 12987 if (p->owner) { 12988 if (!p->refer) { 12989 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 12990 ast_queue_hangup(p->owner); 12991 } else if (option_debug > 3) 12992 ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n"); 12993 } else { 12994 if (p->subscribed == NONE) 12995 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12996 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 12997 /* Ready to send the next state we have on queue */ 12998 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 12999 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 13000 } 13001 } 13002 } else if (sipmethod == SIP_REGISTER) 13003 res = handle_response_register(p, resp, rest, req, ignore, seqno); 13004 else if (sipmethod == SIP_BYE) { /* Ok, we're ready to go */ 13005 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13006 ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 13007 } else if (sipmethod == SIP_SUBSCRIBE) 13008 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 13009 break; 13010 case 202: /* Transfer accepted */ 13011 if (sipmethod == SIP_REFER) 13012 handle_response_refer(p, resp, rest, req, seqno); 13013 break; 13014 case 401: /* Not www-authorized on SIP method */ 13015 if (sipmethod == SIP_INVITE) 13016 handle_response_invite(p, resp, rest, req, seqno); 13017 else if (sipmethod == SIP_REFER) 13018 handle_response_refer(p, resp, rest, req, seqno); 13019 else if (p->registry && sipmethod == SIP_REGISTER) 13020 res = handle_response_register(p, resp, rest, req, ignore, seqno); 13021 else if (sipmethod == SIP_BYE) { 13022 if (ast_strlen_zero(p->authname)) { 13023 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 13024 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 13025 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13026 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "WWW-Authenticate", "Authorization", sipmethod, 0)) { 13027 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13028 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13029 /* We fail to auth bye on our own call, but still needs to tear down the call. 13030 Life, they call it. */ 13031 } 13032 } else { 13033 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 13034 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13035 } 13036 break; 13037 case 403: /* Forbidden - we failed authentication */ 13038 if (sipmethod == SIP_INVITE) 13039 handle_response_invite(p, resp, rest, req, seqno); 13040 else if (p->registry && sipmethod == SIP_REGISTER) 13041 res = handle_response_register(p, resp, rest, req, ignore, seqno); 13042 else { 13043 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 13044 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13045 } 13046 break; 13047 case 404: /* Not found */ 13048 if (p->registry && sipmethod == SIP_REGISTER) 13049 res = handle_response_register(p, resp, rest, req, ignore, seqno); 13050 else if (sipmethod == SIP_INVITE) 13051 handle_response_invite(p, resp, rest, req, seqno); 13052 else if (owner) 13053 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13054 break; 13055 case 407: /* Proxy auth required */ 13056 if (sipmethod == SIP_INVITE) 13057 handle_response_invite(p, resp, rest, req, seqno); 13058 else if (sipmethod == SIP_REFER) 13059 handle_response_refer(p, resp, rest, req, seqno); 13060 else if (p->registry && sipmethod == SIP_REGISTER) 13061 res = handle_response_register(p, resp, rest, req, ignore, seqno); 13062 else if (sipmethod == SIP_BYE) { 13063 if (ast_strlen_zero(p->authname)) { 13064 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 13065 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 13066 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13067 } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 13068 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13069 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13070 } 13071 } else /* We can't handle this, giving up in a bad way */ 13072 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13073 13074 break; 13075 case 408: /* Request timeout - terminate dialog */ 13076 if (sipmethod == SIP_INVITE) 13077 handle_response_invite(p, resp, rest, req, seqno); 13078 else if (sipmethod == SIP_REGISTER) 13079 res = handle_response_register(p, resp, rest, req, ignore, seqno); 13080 else if (sipmethod == SIP_BYE) { 13081 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13082 if (option_debug) 13083 ast_log(LOG_DEBUG, "Got timeout on bye. Thanks for the answer. Now, kill this call\n"); 13084 } else { 13085 if (owner) 13086 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13087 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13088 } 13089 break; 13090 case 481: /* Call leg does not exist */ 13091 if (sipmethod == SIP_INVITE) { 13092 handle_response_invite(p, resp, rest, req, seqno); 13093 } else if (sipmethod == SIP_REFER) { 13094 handle_response_refer(p, resp, rest, req, seqno); 13095 } else if (sipmethod == SIP_BYE) { 13096 /* The other side has no transaction to bye, 13097 just assume it's all right then */ 13098 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13099 } else if (sipmethod == SIP_CANCEL) { 13100 /* The other side has no transaction to cancel, 13101 just assume it's all right then */ 13102 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13103 } else { 13104 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 13105 /* Guessing that this is not an important request */ 13106 } 13107 break; 13108 case 487: 13109 if (sipmethod == SIP_INVITE) 13110 handle_response_invite(p, resp, rest, req, seqno); 13111 break; 13112 case 488: /* Not acceptable here - codec error */ 13113 if (sipmethod == SIP_INVITE) 13114 handle_response_invite(p, resp, rest, req, seqno); 13115 break; 13116 case 491: /* Pending */ 13117 if (sipmethod == SIP_INVITE) 13118 handle_response_invite(p, resp, rest, req, seqno); 13119 else { 13120 if (option_debug) 13121 ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 13122 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13123 } 13124 break; 13125 case 501: /* Not Implemented */ 13126 if (sipmethod == SIP_INVITE) 13127 handle_response_invite(p, resp, rest, req, seqno); 13128 else if (sipmethod == SIP_REFER) 13129 handle_response_refer(p, resp, rest, req, seqno); 13130 else 13131 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg); 13132 break; 13133 case 603: /* Declined transfer */ 13134 if (sipmethod == SIP_REFER) { 13135 handle_response_refer(p, resp, rest, req, seqno); 13136 break; 13137 } 13138 /* Fallthrough */ 13139 default: 13140 if ((resp >= 300) && (resp < 700)) { 13141 /* Fatal response */ 13142 if ((option_verbose > 2) && (resp != 487)) 13143 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 13144 13145 if (sipmethod == SIP_INVITE) 13146 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 13147 13148 /* XXX Locking issues?? XXX */ 13149 switch(resp) { 13150 case 300: /* Multiple Choices */ 13151 case 301: /* Moved permenantly */ 13152 case 302: /* Moved temporarily */ 13153 case 305: /* Use Proxy */ 13154 parse_moved_contact(p, req); 13155 /* Fall through */ 13156 case 486: /* Busy here */ 13157 case 600: /* Busy everywhere */ 13158 case 603: /* Decline */ 13159 if (p->owner) 13160 ast_queue_control(p->owner, AST_CONTROL_BUSY); 13161 break; 13162 case 482: /* 13163 \note SIP is incapable of performing a hairpin call, which 13164 is yet another failure of not having a layer 2 (again, YAY 13165 IETF for thinking ahead). So we treat this as a call 13166 forward and hope we end up at the right place... */ 13167 if (option_debug) 13168 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 13169 if (p->owner) 13170 ast_string_field_build(p->owner, call_forward, 13171 "Local/%s@%s", p->username, p->context); 13172 /* Fall through */ 13173 case 480: /* Temporarily Unavailable */ 13174 case 404: /* Not Found */ 13175 case 410: /* Gone */ 13176 case 400: /* Bad Request */ 13177 case 500: /* Server error */ 13178 if (sipmethod == SIP_REFER) { 13179 handle_response_refer(p, resp, rest, req, seqno); 13180 break; 13181 } 13182 /* Fall through */ 13183 case 502: /* Bad gateway */ 13184 case 503: /* Service Unavailable */ 13185 case 504: /* Server Timeout */ 13186 if (owner) 13187 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 13188 break; 13189 default: 13190 /* Send hangup */ 13191 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE) 13192 ast_queue_hangup(p->owner); 13193 break; 13194 } 13195 /* ACK on invite */ 13196 if (sipmethod == SIP_INVITE) 13197 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 13198 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 13199 sip_alreadygone(p); 13200 if (!p->owner) 13201 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13202 } else if ((resp >= 100) && (resp < 200)) { 13203 if (sipmethod == SIP_INVITE) { 13204 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13205 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13206 if (find_sdp(req)) 13207 process_sdp(p, req); 13208 if (p->owner) { 13209 /* Queue a progress frame */ 13210 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 13211 } 13212 } 13213 } else 13214 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)); 13215 } 13216 } else { 13217 /* Responses to OUTGOING SIP requests on INCOMING calls 13218 get handled here. As well as out-of-call message responses */ 13219 if (ast_test_flag(req, SIP_PKT_DEBUG)) 13220 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 13221 13222 if (sipmethod == SIP_INVITE && resp == 200) { 13223 /* Tags in early session is replaced by the tag in 200 OK, which is 13224 the final reply to our INVITE */ 13225 char tag[128]; 13226 13227 gettag(req, "To", tag, sizeof(tag)); 13228 ast_string_field_set(p, theirtag, tag); 13229 } 13230 13231 switch(resp) { 13232 case 200: 13233 if (sipmethod == SIP_INVITE) { 13234 handle_response_invite(p, resp, rest, req, seqno); 13235 } else if (sipmethod == SIP_CANCEL) { 13236 if (option_debug) 13237 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 13238 13239 /* Wait for 487, then destroy */ 13240 } else if (sipmethod == SIP_NOTIFY) { 13241 /* They got the notify, this is the end */ 13242 if (p->owner) { 13243 if (p->refer) { 13244 if (option_debug) 13245 ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n"); 13246 } else 13247 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 13248 /* ast_queue_hangup(p->owner); Disabled */ 13249 } else { 13250 if (!p->subscribed && !p->refer) 13251 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13252 if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) { 13253 /* Ready to send the next state we have on queue */ 13254 ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE); 13255 cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p); 13256 } 13257 } 13258 } else if (sipmethod == SIP_BYE) 13259 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13260 else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) 13261 /* We successfully transmitted a message or 13262 a video update request in INFO */ 13263 ; 13264 else if (sipmethod == SIP_BYE) 13265 /* Ok, we're ready to go */ 13266 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13267 break; 13268 case 202: /* Transfer accepted */ 13269 if (sipmethod == SIP_REFER) 13270 handle_response_refer(p, resp, rest, req, seqno); 13271 break; 13272 case 401: /* www-auth */ 13273 case 407: 13274 if (sipmethod == SIP_REFER) 13275 handle_response_refer(p, resp, rest, req, seqno); 13276 else if (sipmethod == SIP_INVITE) 13277 handle_response_invite(p, resp, rest, req, seqno); 13278 else if (sipmethod == SIP_BYE) { 13279 char *auth, *auth2; 13280 13281 auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate"); 13282 auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization"); 13283 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 13284 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 13285 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13286 } 13287 } 13288 break; 13289 case 481: /* Call leg does not exist */ 13290 if (sipmethod == SIP_INVITE) { 13291 /* Re-invite failed */ 13292 handle_response_invite(p, resp, rest, req, seqno); 13293 } else if (sipmethod == SIP_BYE) { 13294 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13295 } else if (sipdebug) { 13296 ast_log (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 13297 } 13298 break; 13299 case 501: /* Not Implemented */ 13300 if (sipmethod == SIP_INVITE) 13301 handle_response_invite(p, resp, rest, req, seqno); 13302 else if (sipmethod == SIP_REFER) 13303 handle_response_refer(p, resp, rest, req, seqno); 13304 break; 13305 case 603: /* Declined transfer */ 13306 if (sipmethod == SIP_REFER) { 13307 handle_response_refer(p, resp, rest, req, seqno); 13308 break; 13309 } 13310 /* Fallthrough */ 13311 default: /* Errors without handlers */ 13312 if ((resp >= 100) && (resp < 200)) { 13313 if (sipmethod == SIP_INVITE) { /* re-invite */ 13314 if (!ast_test_flag(req, SIP_PKT_IGNORE) && sip_cancel_destroy(p)) 13315 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13316 } 13317 } 13318 if ((resp >= 300) && (resp < 700)) { 13319 if ((option_verbose > 2) && (resp != 487)) 13320 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)); 13321 switch(resp) { 13322 case 488: /* Not acceptable here - codec error */ 13323 case 603: /* Decline */ 13324 case 500: /* Server error */ 13325 case 502: /* Bad gateway */ 13326 case 503: /* Service Unavailable */ 13327 case 504: /* Server timeout */ 13328 13329 /* re-invite failed */ 13330 if (sipmethod == SIP_INVITE && sip_cancel_destroy(p)) 13331 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 13332 break; 13333 } 13334 } 13335 break; 13336 } 13337 } 13338 }
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 12317 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().
12318 { 12319 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 12320 int res = 0; 12321 int xmitres = 0; 12322 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 12323 struct ast_channel *bridgepeer = NULL; 12324 12325 if (option_debug > 3) { 12326 if (reinvite) 12327 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 12328 else 12329 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 12330 } 12331 12332 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */ 12333 if (option_debug) 12334 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 12335 return; 12336 } 12337 12338 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 12339 /* Don't auto congest anymore since we've gotten something useful back */ 12340 AST_SCHED_DEL(sched, p->initid); 12341 12342 /* RFC3261 says we must treat every 1xx response (but not 100) 12343 that we don't recognize as if it was 183. 12344 */ 12345 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183) 12346 resp = 183; 12347 12348 /* Any response between 100 and 199 is PROCEEDING */ 12349 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 12350 p->invitestate = INV_PROCEEDING; 12351 12352 /* Final response, not 200 ? */ 12353 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 12354 p->invitestate = INV_COMPLETED; 12355 12356 12357 switch (resp) { 12358 case 100: /* Trying */ 12359 case 101: /* Dialog establishment */ 12360 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12361 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12362 check_pendings(p); 12363 break; 12364 12365 case 180: /* 180 Ringing */ 12366 case 182: /* 182 Queued */ 12367 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12368 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12369 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12370 ast_queue_control(p->owner, AST_CONTROL_RINGING); 12371 if (p->owner->_state != AST_STATE_UP) { 12372 ast_setstate(p->owner, AST_STATE_RINGING); 12373 } 12374 } 12375 if (find_sdp(req)) { 12376 if (p->invitestate != INV_CANCELLED) 12377 p->invitestate = INV_EARLY_MEDIA; 12378 res = process_sdp(p, req); 12379 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12380 /* Queue a progress frame only if we have SDP in 180 or 182 */ 12381 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12382 } 12383 } 12384 check_pendings(p); 12385 break; 12386 12387 case 183: /* Session progress */ 12388 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12389 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12390 /* Ignore 183 Session progress without SDP */ 12391 if (find_sdp(req)) { 12392 if (p->invitestate != INV_CANCELLED) 12393 p->invitestate = INV_EARLY_MEDIA; 12394 res = process_sdp(p, req); 12395 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12396 /* Queue a progress frame */ 12397 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12398 } 12399 } 12400 check_pendings(p); 12401 break; 12402 12403 case 200: /* 200 OK on invite - someone's answering our call */ 12404 if (!ast_test_flag(req, SIP_PKT_IGNORE) && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p)) 12405 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 12406 p->authtries = 0; 12407 if (find_sdp(req)) { 12408 if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) 12409 if (!reinvite) 12410 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 12411 /* For re-invites, we try to recover */ 12412 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12413 } 12414 12415 /* Parse contact header for continued conversation */ 12416 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 12417 /* This is important when we have a SIP proxy between us and the phone */ 12418 if (outgoing) { 12419 update_call_counter(p, DEC_CALL_RINGING); 12420 parse_ok_contact(p, req); 12421 /* Save Record-Route for any later requests we make on this dialogue */ 12422 if (!reinvite) 12423 build_route(p, req, 1); 12424 12425 if(set_address_from_contact(p)) { 12426 /* Bad contact - we don't know how to reach this device */ 12427 /* We need to ACK, but then send a bye */ 12428 if (!p->route && !ast_test_flag(req, SIP_PKT_IGNORE)) 12429 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12430 } 12431 12432 } 12433 12434 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 12435 struct sip_pvt *bridgepvt = NULL; 12436 12437 if (!bridgepeer->tech) { 12438 ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n"); 12439 break; 12440 } 12441 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 12442 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 12443 if (bridgepvt->udptl) { 12444 if (p->t38.state == T38_PEER_REINVITE) { 12445 sip_handle_t38_reinvite(bridgepeer, p, 0); 12446 ast_rtp_set_rtptimers_onhold(p->rtp); 12447 if (p->vrtp) 12448 ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */ 12449 } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) { 12450 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 12451 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 12452 /* XXXX Should we really destroy this session here, without any response at all??? */ 12453 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12454 } 12455 } else { 12456 if (option_debug > 1) 12457 ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n"); 12458 ast_mutex_lock(&bridgepvt->lock); 12459 bridgepvt->t38.state = T38_DISABLED; 12460 ast_mutex_unlock(&bridgepvt->lock); 12461 if (option_debug) 12462 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type); 12463 p->t38.state = T38_DISABLED; 12464 if (option_debug > 1) 12465 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12466 } 12467 } else { 12468 /* Other side is not a SIP channel */ 12469 if (option_debug > 1) 12470 ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n"); 12471 p->t38.state = T38_DISABLED; 12472 if (option_debug > 1) 12473 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12474 } 12475 } 12476 if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) { 12477 /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */ 12478 p->t38.state = T38_ENABLED; 12479 if (option_debug) 12480 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 12481 } 12482 12483 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 12484 if (!reinvite) { 12485 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 12486 } else { /* RE-invite */ 12487 ast_queue_frame(p->owner, &ast_null_frame); 12488 } 12489 } else { 12490 /* It's possible we're getting an 200 OK after we've tried to disconnect 12491 by sending CANCEL */ 12492 /* First send ACK, then send bye */ 12493 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12494 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 12495 } 12496 /* If I understand this right, the branch is different for a non-200 ACK only */ 12497 p->invitestate = INV_TERMINATED; 12498 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 12499 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 12500 check_pendings(p); 12501 break; 12502 case 407: /* Proxy authentication */ 12503 case 401: /* Www auth */ 12504 /* First we ACK */ 12505 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12506 if (p->options) 12507 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 12508 12509 /* Then we AUTH */ 12510 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 12511 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12512 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 12513 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 12514 if (p->authtries < MAX_AUTHTRIES) 12515 p->invitestate = INV_CALLING; 12516 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 12517 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 12518 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12519 sip_alreadygone(p); 12520 if (p->owner) 12521 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12522 } 12523 } 12524 break; 12525 12526 case 403: /* Forbidden */ 12527 /* First we ACK */ 12528 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12529 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 12530 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) 12531 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12532 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12533 sip_alreadygone(p); 12534 break; 12535 12536 case 404: /* Not found */ 12537 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12538 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12539 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12540 sip_alreadygone(p); 12541 break; 12542 12543 case 408: /* Request timeout */ 12544 case 481: /* Call leg does not exist */ 12545 /* Could be REFER caused INVITE with replaces */ 12546 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 12547 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12548 if (p->owner) 12549 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12550 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12551 break; 12552 case 487: /* Cancelled transaction */ 12553 /* We have sent CANCEL on an outbound INVITE 12554 This transaction is already scheduled to be killed by sip_hangup(). 12555 */ 12556 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12557 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12558 ast_queue_hangup(p->owner); 12559 append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request"); 12560 } else if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 12561 update_call_counter(p, DEC_CALL_LIMIT); 12562 append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog."); 12563 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12564 sip_alreadygone(p); 12565 } 12566 break; 12567 case 488: /* Not acceptable here */ 12568 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12569 if (reinvite && p->udptl) { 12570 /* If this is a T.38 call, we should go back to 12571 audio. If this is an audio call - something went 12572 terribly wrong since we don't renegotiate codecs, 12573 only IP/port . 12574 */ 12575 p->t38.state = T38_DISABLED; 12576 /* Try to reset RTP timers */ 12577 ast_rtp_set_rtptimers_onhold(p->rtp); 12578 ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n"); 12579 12580 /*! \bug Is there any way we can go back to the audio call on both 12581 sides here? 12582 */ 12583 /* While figuring that out, hangup the call */ 12584 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12585 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12586 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12587 } else if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) { 12588 /* We tried to send T.38 out in an initial INVITE and the remote side rejected it, 12589 right now we can't fall back to audio so totally abort. 12590 */ 12591 p->t38.state = T38_DISABLED; 12592 /* Try to reset RTP timers */ 12593 ast_rtp_set_rtptimers_onhold(p->rtp); 12594 ast_log(LOG_ERROR, "Got error on T.38 initial invite. Bailing out.\n"); 12595 12596 /* The dialog is now terminated */ 12597 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12598 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12599 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12600 sip_alreadygone(p); 12601 } else { 12602 /* We can't set up this call, so give up */ 12603 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 12604 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12605 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12606 /* If there's no dialog to end, then mark p as already gone */ 12607 if (!reinvite) 12608 sip_alreadygone(p); 12609 } 12610 break; 12611 case 491: /* Pending */ 12612 /* we really should have to wait a while, then retransmit 12613 * We should support the retry-after at some point 12614 * At this point, we treat this as a congestion if the call is not in UP state 12615 */ 12616 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12617 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) { 12618 if (p->owner->_state != AST_STATE_UP) { 12619 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12620 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12621 } else { 12622 /* This is a re-invite that failed. 12623 * Reset the flag after a while 12624 */ 12625 int wait = 3 + ast_random() % 5; 12626 p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, p); 12627 if (option_debug > 2) 12628 ast_log(LOG_DEBUG, "Reinvite race. Waiting %d secs before retry\n", wait); 12629 } 12630 } 12631 break; 12632 12633 case 501: /* Not implemented */ 12634 xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12635 if (p->owner) 12636 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12637 break; 12638 } 12639 if (xmitres == XMIT_ERROR) 12640 ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid); 12641 }
static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
int | resp, | |||
struct sip_request * | req | |||
) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 12835 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_tvdiff_ms(), ast_tvnow(), ASTOBJ_REF, ASTOBJ_UNREF, sip_peer::call, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, EVENT_FLAG_SYSTEM, sip_pvt::flags, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::maxms, sip_peer::name, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::relatedpeer, s, sched, sip_destroy_peer(), SIP_NEEDDESTROY, and sip_poke_peer_s().
Referenced by handle_response().
12836 { 12837 struct sip_peer *peer = p->relatedpeer; 12838 int statechanged, is_reachable, was_reachable; 12839 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 12840 12841 /* 12842 * Compute the response time to a ping (goes in peer->lastms.) 12843 * -1 means did not respond, 0 means unknown, 12844 * 1..maxms is a valid response, >maxms means late response. 12845 */ 12846 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 12847 pingtime = 1; 12848 12849 /* Now determine new state and whether it has changed. 12850 * Use some helper variables to simplify the writing 12851 * of the expressions. 12852 */ 12853 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 12854 is_reachable = pingtime <= peer->maxms; 12855 statechanged = peer->lastms == 0 /* yes, unknown before */ 12856 || was_reachable != is_reachable; 12857 12858 peer->lastms = pingtime; 12859 peer->call = NULL; 12860 if (statechanged) { 12861 const char *s = is_reachable ? "Reachable" : "Lagged"; 12862 12863 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 12864 peer->name, s, pingtime, peer->maxms); 12865 ast_device_state_changed("SIP/%s", peer->name); 12866 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 12867 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 12868 peer->name, s, pingtime); 12869 } 12870 12871 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 12872 struct sip_peer *peer_ptr = peer; 12873 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 12874 } 12875 12876 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12877 12878 /* Try again eventually */ 12879 peer->pokeexpire = ast_sched_add(sched, 12880 is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, 12881 sip_poke_peer_s, ASTOBJ_REF(peer)); 12882 12883 if (peer->pokeexpire == -1) { 12884 ASTOBJ_UNREF(peer, sip_destroy_peer); 12885 } 12886 }
static void handle_response_refer | ( | struct sip_pvt * | p, | |
int | resp, | |||
char * | rest, | |||
struct sip_request * | req, | |||
int | seqno | |||
) | [static] |
Definition at line 12646 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().
12647 { 12648 char *auth = "Proxy-Authenticate"; 12649 char *auth2 = "Proxy-Authorization"; 12650 12651 /* If no refer structure exists, then do nothing */ 12652 if (!p->refer) 12653 return; 12654 12655 switch (resp) { 12656 case 202: /* Transfer accepted */ 12657 /* We need to do something here */ 12658 /* The transferee is now sending INVITE to target */ 12659 p->refer->status = REFER_ACCEPTED; 12660 /* Now wait for next message */ 12661 if (option_debug > 2) 12662 ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n"); 12663 /* We should hang along, waiting for NOTIFY's here */ 12664 break; 12665 12666 case 401: /* Not www-authorized on SIP method */ 12667 case 407: /* Proxy auth */ 12668 if (ast_strlen_zero(p->authname)) { 12669 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 12670 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12671 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12672 } 12673 if (resp == 401) { 12674 auth = "WWW-Authenticate"; 12675 auth2 = "Authorization"; 12676 } 12677 if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) { 12678 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 12679 p->refer->status = REFER_NOAUTH; 12680 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12681 } 12682 break; 12683 case 481: /* Call leg does not exist */ 12684 12685 /* A transfer with Replaces did not work */ 12686 /* OEJ: We should Set flag, cancel the REFER, go back 12687 to original call - but right now we can't */ 12688 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 12689 if (p->owner) 12690 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12691 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12692 break; 12693 12694 case 500: /* Server error */ 12695 case 501: /* Method not implemented */ 12696 /* Return to the current call onhold */ 12697 /* Status flag needed to be reset */ 12698 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 12699 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12700 p->refer->status = REFER_FAILED; 12701 break; 12702 case 603: /* Transfer declined */ 12703 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 12704 p->refer->status = REFER_FAILED; 12705 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12706 break; 12707 } 12708 }
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 12711 of file chan_sip.c.
References __get_header(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_strlen_zero(), ASTOBJ_UNREF, sip_pvt::authtries, sip_registry::call, sip_registry::contact, DEFAULT_TRANS_TIMEOUT, do_register_auth(), EVENT_FLAG_SYSTEM, sip_registry::expire, EXPIRY_GUARD_LIMIT, EXPIRY_GUARD_MIN, EXPIRY_GUARD_PCT, EXPIRY_GUARD_SECS, sip_pvt::flags, get_header(), sip_registry::hostname, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, manager_event(), MAX, MAX_AUTHTRIES, option_debug, sip_pvt::our_contact, sip_pvt::peername, sip_registry::refresh, REG_STATE_REGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), sip_registry::regtime, S_OR, sched, SIP_NEEDDESTROY, sip_registry_destroy(), sip_reregister(), sip_scheddestroy(), sipdebug, sip_registry::timeout, sip_pvt::username, and sip_registry::username.
Referenced by handle_response().
12712 { 12713 int expires, expires_ms; 12714 struct sip_registry *r; 12715 r=p->registry; 12716 12717 switch (resp) { 12718 case 401: /* Unauthorized */ 12719 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 12720 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 12721 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12722 } 12723 break; 12724 case 403: /* Forbidden */ 12725 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 12726 if (global_regattempts_max) 12727 p->registry->regattempts = global_regattempts_max+1; 12728 AST_SCHED_DEL(sched, r->timeout); 12729 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12730 break; 12731 case 404: /* Not found */ 12732 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 12733 if (global_regattempts_max) 12734 p->registry->regattempts = global_regattempts_max+1; 12735 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12736 r->call = NULL; 12737 AST_SCHED_DEL(sched, r->timeout); 12738 break; 12739 case 407: /* Proxy auth */ 12740 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 12741 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 12742 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12743 } 12744 break; 12745 case 408: /* Request timeout */ 12746 /* Got a timeout response, so reset the counter of failed responses */ 12747 r->regattempts = 0; 12748 break; 12749 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 12750 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 12751 if (global_regattempts_max) 12752 p->registry->regattempts = global_regattempts_max+1; 12753 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12754 r->call = NULL; 12755 AST_SCHED_DEL(sched, r->timeout); 12756 break; 12757 case 200: /* 200 OK */ 12758 if (!r) { 12759 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)); 12760 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12761 return 0; 12762 } 12763 12764 r->regstate = REG_STATE_REGISTERED; 12765 r->regtime = time(NULL); /* Reset time of last succesful registration */ 12766 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 12767 r->regattempts = 0; 12768 if (option_debug) 12769 ast_log(LOG_DEBUG, "Registration successful\n"); 12770 if (r->timeout > -1) { 12771 if (option_debug) 12772 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 12773 } 12774 AST_SCHED_DEL(sched, r->timeout); 12775 r->call = NULL; 12776 p->registry = NULL; 12777 /* Let this one hang around until we have all the responses */ 12778 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12779 /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */ 12780 12781 /* set us up for re-registering */ 12782 /* figure out how long we got registered for */ 12783 AST_SCHED_DEL(sched, r->expire); 12784 /* according to section 6.13 of RFC, contact headers override 12785 expires headers, so check those first */ 12786 expires = 0; 12787 12788 /* XXX todo: try to save the extra call */ 12789 if (!ast_strlen_zero(get_header(req, "Contact"))) { 12790 const char *contact = NULL; 12791 const char *tmptmp = NULL; 12792 int start = 0; 12793 for(;;) { 12794 contact = __get_header(req, "Contact", &start); 12795 /* this loop ensures we get a contact header about our register request */ 12796 if(!ast_strlen_zero(contact)) { 12797 if( (tmptmp=strstr(contact, p->our_contact))) { 12798 contact=tmptmp; 12799 break; 12800 } 12801 } else 12802 break; 12803 } 12804 tmptmp = strcasestr(contact, "expires="); 12805 if (tmptmp) { 12806 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 12807 expires = 0; 12808 } 12809 12810 } 12811 if (!expires) 12812 expires=atoi(get_header(req, "expires")); 12813 if (!expires) 12814 expires=default_expiry; 12815 12816 expires_ms = expires * 1000; 12817 if (expires <= EXPIRY_GUARD_LIMIT) 12818 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 12819 else 12820 expires_ms -= EXPIRY_GUARD_SECS * 1000; 12821 if (sipdebug) 12822 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 12823 12824 r->refresh= (int) expires_ms / 1000; 12825 12826 /* Schedule re-registration before we expire */ 12827 AST_SCHED_DEL(sched, r->expire); 12828 r->expire = ast_sched_add(sched, expires_ms, sip_reregister, r); 12829 ASTOBJ_UNREF(r, sip_registry_destroy); 12830 } 12831 return 1; 12832 }
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 3479 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().
03480 { 03481 switch (cause) { 03482 case AST_CAUSE_UNALLOCATED: /* 1 */ 03483 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 03484 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 03485 return "404 Not Found"; 03486 case AST_CAUSE_CONGESTION: /* 34 */ 03487 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 03488 return "503 Service Unavailable"; 03489 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 03490 return "408 Request Timeout"; 03491 case AST_CAUSE_NO_ANSWER: /* 19 */ 03492 case AST_CAUSE_UNREGISTERED: /* 20 */ 03493 return "480 Temporarily unavailable"; 03494 case AST_CAUSE_CALL_REJECTED: /* 21 */ 03495 return "403 Forbidden"; 03496 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 03497 return "410 Gone"; 03498 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 03499 return "480 Temporarily unavailable"; 03500 case AST_CAUSE_INVALID_NUMBER_FORMAT: 03501 return "484 Address incomplete"; 03502 case AST_CAUSE_USER_BUSY: 03503 return "486 Busy here"; 03504 case AST_CAUSE_FAILURE: 03505 return "500 Server internal failure"; 03506 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 03507 return "501 Not Implemented"; 03508 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 03509 return "503 Service Unavailable"; 03510 /* Used in chan_iax2 */ 03511 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 03512 return "502 Bad Gateway"; 03513 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 03514 return "488 Not Acceptable Here"; 03515 03516 case AST_CAUSE_NOTDEFINED: 03517 default: 03518 if (option_debug) 03519 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 03520 return NULL; 03521 } 03522 03523 /* Never reached */ 03524 return 0; 03525 }
static int hangup_sip2cause | ( | int | cause | ) | [static] |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 3367 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().
03368 { 03369 /* Possible values taken from causes.h */ 03370 03371 switch(cause) { 03372 case 401: /* Unauthorized */ 03373 return AST_CAUSE_CALL_REJECTED; 03374 case 403: /* Not found */ 03375 return AST_CAUSE_CALL_REJECTED; 03376 case 404: /* Not found */ 03377 return AST_CAUSE_UNALLOCATED; 03378 case 405: /* Method not allowed */ 03379 return AST_CAUSE_INTERWORKING; 03380 case 407: /* Proxy authentication required */ 03381 return AST_CAUSE_CALL_REJECTED; 03382 case 408: /* No reaction */ 03383 return AST_CAUSE_NO_USER_RESPONSE; 03384 case 409: /* Conflict */ 03385 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 03386 case 410: /* Gone */ 03387 return AST_CAUSE_UNALLOCATED; 03388 case 411: /* Length required */ 03389 return AST_CAUSE_INTERWORKING; 03390 case 413: /* Request entity too large */ 03391 return AST_CAUSE_INTERWORKING; 03392 case 414: /* Request URI too large */ 03393 return AST_CAUSE_INTERWORKING; 03394 case 415: /* Unsupported media type */ 03395 return AST_CAUSE_INTERWORKING; 03396 case 420: /* Bad extension */ 03397 return AST_CAUSE_NO_ROUTE_DESTINATION; 03398 case 480: /* No answer */ 03399 return AST_CAUSE_NO_ANSWER; 03400 case 481: /* No answer */ 03401 return AST_CAUSE_INTERWORKING; 03402 case 482: /* Loop detected */ 03403 return AST_CAUSE_INTERWORKING; 03404 case 483: /* Too many hops */ 03405 return AST_CAUSE_NO_ANSWER; 03406 case 484: /* Address incomplete */ 03407 return AST_CAUSE_INVALID_NUMBER_FORMAT; 03408 case 485: /* Ambigous */ 03409 return AST_CAUSE_UNALLOCATED; 03410 case 486: /* Busy everywhere */ 03411 return AST_CAUSE_BUSY; 03412 case 487: /* Request terminated */ 03413 return AST_CAUSE_INTERWORKING; 03414 case 488: /* No codecs approved */ 03415 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03416 case 491: /* Request pending */ 03417 return AST_CAUSE_INTERWORKING; 03418 case 493: /* Undecipherable */ 03419 return AST_CAUSE_INTERWORKING; 03420 case 500: /* Server internal failure */ 03421 return AST_CAUSE_FAILURE; 03422 case 501: /* Call rejected */ 03423 return AST_CAUSE_FACILITY_REJECTED; 03424 case 502: 03425 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03426 case 503: /* Service unavailable */ 03427 return AST_CAUSE_CONGESTION; 03428 case 504: /* Gateway timeout */ 03429 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 03430 case 505: /* SIP version not supported */ 03431 return AST_CAUSE_INTERWORKING; 03432 case 600: /* Busy everywhere */ 03433 return AST_CAUSE_USER_BUSY; 03434 case 603: /* Decline */ 03435 return AST_CAUSE_CALL_REJECTED; 03436 case 604: /* Does not exist anywhere */ 03437 return AST_CAUSE_UNALLOCATED; 03438 case 606: /* Not acceptable */ 03439 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03440 default: 03441 return AST_CAUSE_NORMAL; 03442 } 03443 /* Never reached */ 03444 return 0; 03445 }
static int init_req | ( | struct sip_request * | req, | |
int | sipmethod, | |||
const char * | recip | |||
) | [static] |
Initialize SIP request.
Definition at line 6000 of file chan_sip.c.
References sip_methods, and cfsip_methods::text.
06001 { 06002 /* Initialize a request */ 06003 memset(req, 0, sizeof(*req)); 06004 req->method = sipmethod; 06005 req->header[0] = req->data; 06006 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 06007 req->len = strlen(req->header[0]); 06008 req->headers++; 06009 return 0; 06010 }
static int init_resp | ( | struct sip_request * | resp, | |
const char * | msg | |||
) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 5987 of file chan_sip.c.
References SIP_RESPONSE.
05988 { 05989 /* Initialize a response */ 05990 memset(resp, 0, sizeof(*resp)); 05991 resp->method = SIP_RESPONSE; 05992 resp->header[0] = resp->data; 05993 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 05994 resp->len = strlen(resp->header[0]); 05995 resp->headers++; 05996 return 0; 05997 }
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 1659 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().
01660 { 01661 if (p->initreq.headers && option_debug) { 01662 ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 01663 } 01664 /* Use this as the basis */ 01665 copy_request(&p->initreq, req); 01666 parse_request(&p->initreq); 01667 if (ast_test_flag(req, SIP_PKT_DEBUG)) 01668 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 01669 }
static void initreqprep | ( | struct sip_request * | req, | |
struct sip_pvt * | p, | |||
int | sipmethod | |||
) | [static] |
Initiate new SIP request to peer/user.
Definition at line 7093 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().
07094 { 07095 char invite_buf[256] = ""; 07096 char *invite = invite_buf; 07097 size_t invite_max = sizeof(invite_buf); 07098 char from[256]; 07099 char to[256]; 07100 char tmp[SIPBUFSIZE/2]; 07101 char tmp2[SIPBUFSIZE/2]; 07102 const char *l = NULL, *n = NULL; 07103 const char *urioptions = ""; 07104 07105 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 07106 const char *s = p->username; /* being a string field, cannot be NULL */ 07107 07108 /* Test p->username against allowed characters in AST_DIGIT_ANY 07109 If it matches the allowed characters list, then sipuser = ";user=phone" 07110 If not, then sipuser = "" 07111 */ 07112 /* + is allowed in first position in a tel: uri */ 07113 if (*s == '+') 07114 s++; 07115 for (; *s; s++) { 07116 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 07117 break; 07118 } 07119 /* If we have only digits, add ;user=phone to the uri */ 07120 if (!*s) 07121 urioptions = ";user=phone"; 07122 } 07123 07124 07125 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 07126 07127 if (p->owner) { 07128 l = p->owner->cid.cid_num; 07129 n = p->owner->cid.cid_name; 07130 } 07131 /* if we are not sending RPID and user wants his callerid restricted */ 07132 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 07133 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 07134 l = CALLERID_UNKNOWN; 07135 n = l; 07136 } 07137 if (ast_strlen_zero(l)) 07138 l = default_callerid; 07139 if (ast_strlen_zero(n)) 07140 n = l; 07141 /* Allow user to be overridden */ 07142 if (!ast_strlen_zero(p->fromuser)) 07143 l = p->fromuser; 07144 else /* Save for any further attempts */ 07145 ast_string_field_set(p, fromuser, l); 07146 07147 /* Allow user to be overridden */ 07148 if (!ast_strlen_zero(p->fromname)) 07149 n = p->fromname; 07150 else /* Save for any further attempts */ 07151 ast_string_field_set(p, fromname, n); 07152 07153 if (pedanticsipchecking) { 07154 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07155 n = tmp; 07156 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 07157 l = tmp2; 07158 } 07159 07160 if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain)) 07161 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); 07162 else 07163 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag); 07164 07165 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 07166 if (!ast_strlen_zero(p->fullcontact)) { 07167 /* If we have full contact, trust it */ 07168 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 07169 } else { 07170 /* Otherwise, use the username while waiting for registration */ 07171 ast_build_string(&invite, &invite_max, "sip:"); 07172 if (!ast_strlen_zero(p->username)) { 07173 n = p->username; 07174 if (pedanticsipchecking) { 07175 ast_uri_encode(n, tmp, sizeof(tmp), 0); 07176 n = tmp; 07177 } 07178 ast_build_string(&invite, &invite_max, "%s@", n); 07179 } 07180 ast_build_string(&invite, &invite_max, "%s", p->tohost); 07181 if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT) 07182 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 07183 ast_build_string(&invite, &invite_max, "%s", urioptions); 07184 } 07185 07186 /* If custom URI options have been provided, append them */ 07187 if (p->options && !ast_strlen_zero(p->options->uri_options)) 07188 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 07189 07190 ast_string_field_set(p, uri, invite_buf); 07191 07192 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 07193 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 07194 snprintf(to, sizeof(to), "<%s%s>;tag=%s", (!strncasecmp(p->uri, "sip:", 4) ? "" : "sip:"), p->uri, p->theirtag); 07195 } else if (p->options && p->options->vxml_url) { 07196 /* If there is a VXML URL append it to the SIP URL */ 07197 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 07198 } else 07199 snprintf(to, sizeof(to), "<%s>", p->uri); 07200 07201 init_req(req, sipmethod, p->uri); 07202 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 07203 07204 add_header(req, "Via", p->via); 07205 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 07206 * OTOH, then we won't have anything in p->route anyway */ 07207 /* Build Remote Party-ID and From */ 07208 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 07209 build_rpid(p); 07210 add_header(req, "From", p->rpid_from); 07211 } else 07212 add_header(req, "From", from); 07213 add_header(req, "To", to); 07214 ast_string_field_set(p, exten, l); 07215 build_contact(p); 07216 add_header(req, "Contact", p->our_contact); 07217 add_header(req, "Call-ID", p->callid); 07218 add_header(req, "CSeq", tmp); 07219 if (!ast_strlen_zero(global_useragent)) 07220 add_header(req, "User-Agent", global_useragent); 07221 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07222 if (!ast_strlen_zero(p->rpid)) 07223 add_header(req, "Remote-Party-ID", p->rpid); 07224 }
static const char * insecure2str | ( | int | port, | |
int | invite | |||
) | const [static] |
Convert Insecure setting to printable string.
Definition at line 10318 of file chan_sip.c.
Referenced by _sip_show_peer().
10319 { 10320 if (port && invite) 10321 return "port,invite"; 10322 else if (port) 10323 return "port"; 10324 else if (invite) 10325 return "invite"; 10326 else 10327 return "no"; 10328 }
static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 8452 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
08453 { 08454 if (!route) 08455 ast_verbose("list_route: no route\n"); 08456 else { 08457 for (;route; route = route->next) 08458 ast_verbose("list_route: hop: <%s>\n", route->hop); 08459 } 08460 }
static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 18787 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.
18788 { 18789 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 18790 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 18791 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 18792 18793 if (!(sched = sched_context_create())) { 18794 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 18795 return AST_MODULE_LOAD_FAILURE; 18796 } 18797 18798 if (!(io = io_context_create())) { 18799 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 18800 sched_context_destroy(sched); 18801 return AST_MODULE_LOAD_FAILURE; 18802 } 18803 18804 sip_reloadreason = CHANNEL_MODULE_LOAD; 18805 18806 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 18807 return AST_MODULE_LOAD_DECLINE; 18808 18809 /* Make sure we can register our sip channel type */ 18810 if (ast_channel_register(&sip_tech)) { 18811 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 18812 io_context_destroy(io); 18813 sched_context_destroy(sched); 18814 return AST_MODULE_LOAD_FAILURE; 18815 } 18816 18817 /* Register all CLI functions for SIP */ 18818 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 18819 18820 /* Tell the RTP subdriver that we're here */ 18821 ast_rtp_proto_register(&sip_rtp); 18822 18823 /* Tell the UDPTL subdriver that we're here */ 18824 ast_udptl_proto_register(&sip_udptl); 18825 18826 /* Register dialplan applications */ 18827 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 18828 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 18829 18830 /* Register dialplan functions */ 18831 ast_custom_function_register(&sip_header_function); 18832 ast_custom_function_register(&sippeer_function); 18833 ast_custom_function_register(&sipchaninfo_function); 18834 ast_custom_function_register(&checksipdomain_function); 18835 18836 /* Register manager commands */ 18837 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 18838 "List SIP peers (text format)", mandescr_show_peers); 18839 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 18840 "Show SIP peer (text format)", mandescr_show_peer); 18841 18842 sip_poke_all_peers(); 18843 sip_send_all_registers(); 18844 18845 /* And start the monitor for the first time */ 18846 restart_monitor(); 18847 18848 return AST_MODULE_LOAD_SUCCESS; 18849 }
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 14783 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().
14784 { 14785 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 14786 /* Chan 2: Call from Asterisk to target */ 14787 int res = 0; 14788 struct sip_pvt *targetcall_pvt; 14789 14790 /* Check if the call ID of the replaces header does exist locally */ 14791 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 14792 transferer->refer->replaces_callid_fromtag))) { 14793 if (transferer->refer->localtransfer) { 14794 /* We did not find the refered call. Sorry, can't accept then */ 14795 transmit_response(transferer, "202 Accepted", req); 14796 /* Let's fake a response from someone else in order 14797 to follow the standard */ 14798 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 14799 append_history(transferer, "Xfer", "Refer failed"); 14800 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 14801 transferer->refer->status = REFER_FAILED; 14802 return -1; 14803 } 14804 /* Fall through for remote transfers that we did not find locally */ 14805 if (option_debug > 2) 14806 ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 14807 return 0; 14808 } 14809 14810 /* Ok, we can accept this transfer */ 14811 transmit_response(transferer, "202 Accepted", req); 14812 append_history(transferer, "Xfer", "Refer accepted"); 14813 if (!targetcall_pvt->owner) { /* No active channel */ 14814 if (option_debug > 3) 14815 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n"); 14816 /* Cancel transfer */ 14817 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 14818 append_history(transferer, "Xfer", "Refer failed"); 14819 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 14820 transferer->refer->status = REFER_FAILED; 14821 ast_mutex_unlock(&targetcall_pvt->lock); 14822 ast_channel_unlock(current->chan1); 14823 return -1; 14824 } 14825 14826 /* We have a channel, find the bridge */ 14827 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 14828 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 14829 14830 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 14831 /* Wrong state of new channel */ 14832 if (option_debug > 3) { 14833 if (target.chan2) 14834 ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 14835 else if (target.chan1->_state != AST_STATE_RING) 14836 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n"); 14837 else 14838 ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n"); 14839 } 14840 } 14841 14842 /* Transfer */ 14843 if (option_debug > 3 && sipdebug) { 14844 if (current->chan2) /* We have two bridges */ 14845 ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 14846 else /* One bridge, propably transfer of IVR/voicemail etc */ 14847 ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 14848 } 14849 14850 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14851 14852 /* Perform the transfer */ 14853 res = attempt_transfer(current, &target); 14854 ast_mutex_unlock(&targetcall_pvt->lock); 14855 if (res) { 14856 /* Failed transfer */ 14857 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE); 14858 append_history(transferer, "Xfer", "Refer failed"); 14859 transferer->refer->status = REFER_FAILED; 14860 if (targetcall_pvt->owner) 14861 ast_channel_unlock(targetcall_pvt->owner); 14862 /* Right now, we have to hangup, sorry. Bridge is destroyed */ 14863 if (res != -2) 14864 ast_hangup(transferer->owner); 14865 else 14866 ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); 14867 } else { 14868 /* Transfer succeeded! */ 14869 14870 /* Tell transferer that we're done. */ 14871 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 14872 append_history(transferer, "Xfer", "Refer succeeded"); 14873 transferer->refer->status = REFER_200OK; 14874 if (targetcall_pvt->owner) { 14875 if (option_debug) 14876 ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 14877 ast_channel_unlock(targetcall_pvt->owner); 14878 } 14879 } 14880 return 1; 14881 }
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 4856 of file chan_sip.c.
References t.
Referenced by sipsock_read().
04857 { 04858 int h = 0, t = 0; 04859 int lws = 0; 04860 04861 for (; h < len;) { 04862 /* Eliminate all CRs */ 04863 if (msgbuf[h] == '\r') { 04864 h++; 04865 continue; 04866 } 04867 /* Check for end-of-line */ 04868 if (msgbuf[h] == '\n') { 04869 /* Check for end-of-message */ 04870 if (h + 1 == len) 04871 break; 04872 /* Check for a continuation line */ 04873 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 04874 /* Merge continuation line */ 04875 h++; 04876 continue; 04877 } 04878 /* Propagate LF and start new line */ 04879 msgbuf[t++] = msgbuf[h++]; 04880 lws = 0; 04881 continue; 04882 } 04883 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 04884 if (lws) { 04885 h++; 04886 continue; 04887 } 04888 msgbuf[t++] = msgbuf[h++]; 04889 lws = 1; 04890 continue; 04891 } 04892 msgbuf[t++] = msgbuf[h++]; 04893 if (lws) 04894 lws = 0; 04895 } 04896 msgbuf[t] = '\0'; 04897 return t; 04898 }
static void make_our_tag | ( | char * | tagbuf, | |
size_t | len | |||
) | [static] |
Make our SIP dialog tag.
Definition at line 4521 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().
04522 { 04523 snprintf(tagbuf, len, "as%08lx", ast_random()); 04524 }
static int manager_sip_show_peer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10563 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().
10564 { 10565 const char *a[4]; 10566 const char *peer; 10567 int ret; 10568 10569 peer = astman_get_header(m,"Peer"); 10570 if (ast_strlen_zero(peer)) { 10571 astman_send_error(s, m, "Peer: <name> missing."); 10572 return 0; 10573 } 10574 a[0] = "sip"; 10575 a[1] = "show"; 10576 a[2] = "peer"; 10577 a[3] = peer; 10578 10579 ret = _sip_show_peer(1, -1, s, m, 4, a); 10580 astman_append(s, "\r\n\r\n" ); 10581 return ret; 10582 }
static int manager_sip_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show SIP peers in the manager API.
Definition at line 10114 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().
10115 { 10116 const char *id = astman_get_header(m,"ActionID"); 10117 const char *a[] = {"sip", "show", "peers"}; 10118 char idtext[256] = ""; 10119 int total = 0; 10120 10121 if (!ast_strlen_zero(id)) 10122 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 10123 10124 astman_send_ack(s, m, "Peer status list will follow"); 10125 /* List the peers in separate manager events */ 10126 _sip_show_peers(-1, &total, s, m, 3, a); 10127 /* Send final confirmation */ 10128 astman_append(s, 10129 "Event: PeerlistComplete\r\n" 10130 "ListItems: %d\r\n" 10131 "%s" 10132 "\r\n", total, idtext); 10133 return 0; 10134 }
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 1685 of file chan_sip.c.
References sip_request::len, sip_methods, and text.
Referenced by __sip_semi_ack(), and find_sip_method().
01686 { 01687 int len = strlen(sip_methods[id].text); 01688 int l_name = name ? strlen(name) : 0; 01689 /* true if the string is long enough, and ends with whitespace, and matches */ 01690 return (l_name >= len && name[len] < 33 && 01691 !strncasecmp(sip_methods[id].text, name, len)); 01692 }
static char * nat2str | ( | int | nat | ) | const [static] |
Convert NAT setting to text string.
Definition at line 10017 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().
10018 { 10019 switch(nat) { 10020 case SIP_NAT_NEVER: 10021 return "No"; 10022 case SIP_NAT_ROUTE: 10023 return "Route"; 10024 case SIP_NAT_ALWAYS: 10025 return "Always"; 10026 case SIP_NAT_RFC3581: 10027 return "RFC3581"; 10028 default: 10029 return "Unknown"; 10030 } 10031 }
static void parse_copy | ( | struct sip_request * | dst, | |
const struct sip_request * | src | |||
) | [static] |
Copy SIP request, parse it.
Definition at line 2264 of file chan_sip.c.
References sip_request::data, sip_request::len, and parse_request().
Referenced by send_request(), and send_response().
02265 { 02266 memset(dst, 0, sizeof(*dst)); 02267 memcpy(dst->data, src->data, sizeof(dst->data)); 02268 dst->len = src->len; 02269 parse_request(dst); 02270 }
static void parse_moved_contact | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Parse 302 Moved temporalily response.
Definition at line 12218 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().
12219 { 12220 char tmp[SIPBUFSIZE]; 12221 char *s, *e, *uri, *t; 12222 char *domain; 12223 12224 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 12225 if ((t = strchr(tmp, ','))) 12226 *t = '\0'; 12227 s = get_in_brackets(tmp); 12228 uri = ast_strdupa(s); 12229 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 12230 if (!strncasecmp(s, "sip:", 4)) 12231 s += 4; 12232 e = strchr(s, ';'); 12233 if (e) 12234 *e = '\0'; 12235 if (option_debug) 12236 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 12237 if (p->owner) 12238 ast_string_field_build(p->owner, call_forward, "SIP/%s", s); 12239 } else { 12240 e = strchr(tmp, '@'); 12241 if (e) { 12242 *e++ = '\0'; 12243 domain = e; 12244 } else { 12245 /* No username part */ 12246 domain = tmp; 12247 } 12248 e = strchr(s, ';'); /* Strip of parameters in the username part */ 12249 if (e) 12250 *e = '\0'; 12251 e = strchr(domain, ';'); /* Strip of parameters in the domain part */ 12252 if (e) 12253 *e = '\0'; 12254 12255 if (!strncasecmp(s, "sip:", 4)) 12256 s += 4; 12257 if (option_debug > 1) 12258 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 12259 if (p->owner) { 12260 pbx_builtin_setvar_helper(p->owner, "SIPREDIRECTURI", uri); 12261 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 12262 ast_string_field_set(p->owner, call_forward, s); 12263 } 12264 } 12265 }
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 8181 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().
08182 { 08183 char contact[SIPBUFSIZE]; 08184 char *c; 08185 08186 /* Look for brackets */ 08187 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08188 c = get_in_brackets(contact); 08189 08190 /* Save full contact to call pvt for later bye or re-invite */ 08191 ast_string_field_set(pvt, fullcontact, c); 08192 08193 /* Save URI for later ACKs, BYE or RE-invites */ 08194 ast_string_field_set(pvt, okcontacturi, c); 08195 08196 /* We should return false for URI:s we can't handle, 08197 like sips:, tel:, mailto:,ldap: etc */ 08198 return TRUE; 08199 }
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 8270 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().
08271 { 08272 char contact[SIPBUFSIZE]; 08273 char data[SIPBUFSIZE]; 08274 const char *expires = get_header(req, "Expires"); 08275 int expiry = atoi(expires); 08276 char *curi, *n, *pt; 08277 int port; 08278 const char *useragent; 08279 struct hostent *hp; 08280 struct ast_hostent ahp; 08281 struct sockaddr_in oldsin, testsin; 08282 08283 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 08284 08285 if (ast_strlen_zero(expires)) { /* No expires header */ 08286 expires = strcasestr(contact, ";expires="); 08287 if (expires) { 08288 /* XXX bug here, we overwrite the string */ 08289 expires = strsep((char **) &expires, ";"); /* trim ; and beyond */ 08290 if (sscanf(expires + 9, "%d", &expiry) != 1) 08291 expiry = default_expiry; 08292 } else { 08293 /* Nothing has been specified */ 08294 expiry = default_expiry; 08295 } 08296 } 08297 08298 /* Look for brackets */ 08299 curi = contact; 08300 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 08301 strsep(&curi, ";"); /* This is Header options, not URI options */ 08302 curi = get_in_brackets(contact); 08303 08304 /* if they did not specify Contact: or Expires:, they are querying 08305 what we currently have stored as their contact address, so return 08306 it 08307 */ 08308 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 08309 /* If we have an active registration, tell them when the registration is going to expire */ 08310 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 08311 pvt->expiry = ast_sched_when(sched, peer->expire); 08312 return PARSE_REGISTER_QUERY; 08313 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 08314 /* This means remove all registrations and return OK */ 08315 memset(&peer->addr, 0, sizeof(peer->addr)); 08316 if (!AST_SCHED_DEL(sched, peer->expire)) { 08317 struct sip_peer *peer_ptr = peer; 08318 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08319 } 08320 08321 destroy_association(peer); 08322 08323 register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */ 08324 peer->fullcontact[0] = '\0'; 08325 peer->useragent[0] = '\0'; 08326 peer->sipoptions = 0; 08327 peer->lastms = 0; 08328 pvt->expiry = 0; 08329 08330 if (option_verbose > 2) 08331 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name); 08332 08333 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name); 08334 return PARSE_REGISTER_UPDATE; 08335 } 08336 08337 /* Store whatever we got as a contact from the client */ 08338 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 08339 08340 /* For the 200 OK, we should use the received contact */ 08341 ast_string_field_build(pvt, our_contact, "<%s>", curi); 08342 08343 /* Make sure it's a SIP URL */ 08344 if (strncasecmp(curi, "sip:", 4)) { 08345 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 08346 } else 08347 curi += 4; 08348 /* Ditch q */ 08349 curi = strsep(&curi, ";"); 08350 /* Grab host */ 08351 n = strchr(curi, '@'); 08352 if (!n) { 08353 n = curi; 08354 curi = NULL; 08355 } else 08356 *n++ = '\0'; 08357 pt = strchr(n, ':'); 08358 if (pt) { 08359 *pt++ = '\0'; 08360 port = atoi(pt); 08361 } else 08362 port = STANDARD_SIP_PORT; 08363 oldsin = peer->addr; 08364 08365 /* Check that they're allowed to register at this IP */ 08366 /* XXX This could block for a long time XXX */ 08367 hp = ast_gethostbyname(n, &ahp); 08368 if (!hp) { 08369 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 08370 *peer->fullcontact = '\0'; 08371 ast_string_field_set(pvt, our_contact, ""); 08372 return PARSE_REGISTER_FAILED; 08373 } 08374 memcpy(&testsin.sin_addr, hp->h_addr, sizeof(testsin.sin_addr)); 08375 if ( ast_apply_ha(global_contact_ha, &testsin) != AST_SENSE_ALLOW || 08376 ast_apply_ha(peer->contactha, &testsin) != AST_SENSE_ALLOW) { 08377 ast_log(LOG_WARNING, "Host '%s' disallowed by rule\n", n); 08378 *peer->fullcontact = '\0'; 08379 ast_string_field_set(pvt, our_contact, ""); 08380 return PARSE_REGISTER_FAILED; 08381 } 08382 08383 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 08384 peer->addr.sin_family = AF_INET; 08385 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 08386 peer->addr.sin_port = htons(port); 08387 } else { 08388 /* Don't trust the contact field. Just use what they came to us 08389 with */ 08390 peer->addr = pvt->recv; 08391 } 08392 08393 /* Save SIP options profile */ 08394 peer->sipoptions = pvt->sipoptions; 08395 08396 if (curi && ast_strlen_zero(peer->username)) 08397 ast_copy_string(peer->username, curi, sizeof(peer->username)); 08398 08399 if (!AST_SCHED_DEL(sched, peer->expire)) { 08400 struct sip_peer *peer_ptr = peer; 08401 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08402 } 08403 if (expiry > max_expiry) 08404 expiry = max_expiry; 08405 if (expiry < min_expiry) 08406 expiry = min_expiry; 08407 if (ast_test_flag(&peer->flags[0], SIP_REALTIME) && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 08408 peer->expire = -1; 08409 } else { 08410 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08411 if (peer->expire == -1) { 08412 struct sip_peer *peer_ptr = peer; 08413 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08414 } 08415 } 08416 pvt->expiry = expiry; 08417 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); 08418 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08419 ast_db_put("SIP/Registry", peer->name, data); 08420 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08421 08422 /* Is this a new IP address for us? */ 08423 if (option_verbose > 2 && inaddrcmp(&peer->addr, &oldsin)) { 08424 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)); 08425 } 08426 sip_poke_peer(peer); 08427 register_peer_exten(peer, 1); 08428 08429 /* Save User agent */ 08430 useragent = get_header(req, "User-Agent"); 08431 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 08432 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 08433 if (option_verbose > 3) 08434 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 08435 } 08436 return PARSE_REGISTER_UPDATE; 08437 }
static int parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 4903 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().
04904 { 04905 /* Divide fields by NULL's */ 04906 char *c; 04907 int f = 0; 04908 04909 c = req->data; 04910 04911 /* First header starts immediately */ 04912 req->header[f] = c; 04913 while(*c) { 04914 if (*c == '\n') { 04915 /* We've got a new header */ 04916 *c = 0; 04917 04918 if (sipdebug && option_debug > 3) 04919 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04920 if (ast_strlen_zero(req->header[f])) { 04921 /* Line by itself means we're now in content */ 04922 c++; 04923 break; 04924 } 04925 if (f >= SIP_MAX_HEADERS - 1) { 04926 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 04927 } else { 04928 f++; 04929 req->header[f] = c + 1; 04930 } 04931 } else if (*c == '\r') { 04932 /* Ignore but eliminate \r's */ 04933 *c = 0; 04934 } 04935 c++; 04936 } 04937 04938 req->headers = f; 04939 04940 /* Check a non-newline-terminated last header */ 04941 if (!ast_strlen_zero(req->header[f])) { 04942 if (sipdebug && option_debug > 3) 04943 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04944 req->headers++; 04945 } 04946 04947 /* Now we process any body content */ 04948 f = 0; 04949 req->line[f] = c; 04950 while (*c) { 04951 if (*c == '\n') { 04952 /* We've got a new line */ 04953 *c = 0; 04954 if (sipdebug && option_debug > 3) 04955 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 04956 if (f == SIP_MAX_LINES - 1) { 04957 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 04958 break; 04959 } else { 04960 f++; 04961 req->line[f] = c + 1; 04962 } 04963 } else if (*c == '\r') { 04964 /* Ignore and eliminate \r's */ 04965 *c = 0; 04966 } 04967 c++; 04968 } 04969 04970 req->lines = f; 04971 04972 /* Check a non-newline-terminated last line */ 04973 if (!ast_strlen_zero(req->line[f])) { 04974 req->lines++; 04975 } 04976 04977 if (*c) 04978 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 04979 04980 /* Split up the first line parts */ 04981 return determine_firstline_parts(req); 04982 }
static unsigned int parse_sip_options | ( | struct sip_pvt * | pvt, | |
const char * | supported | |||
) | [static] |
Parse supported header in incoming packet.
Definition at line 1709 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().
01710 { 01711 char *next, *sep; 01712 char *temp; 01713 unsigned int profile = 0; 01714 int i, found; 01715 01716 if (ast_strlen_zero(supported) ) 01717 return 0; 01718 temp = ast_strdupa(supported); 01719 01720 if (option_debug > 2 && sipdebug) 01721 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01722 01723 for (next = temp; next; next = sep) { 01724 found = FALSE; 01725 if ( (sep = strchr(next, ',')) != NULL) 01726 *sep++ = '\0'; 01727 next = ast_skip_blanks(next); 01728 if (option_debug > 2 && sipdebug) 01729 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01730 for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) { 01731 if (!strcasecmp(next, sip_options[i].text)) { 01732 profile |= sip_options[i].id; 01733 found = TRUE; 01734 if (option_debug > 2 && sipdebug) 01735 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01736 break; 01737 } 01738 } 01739 if (!found && option_debug > 2 && sipdebug) { 01740 if (!strncasecmp(next, "x-", 2)) 01741 ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next); 01742 else 01743 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01744 } 01745 } 01746 01747 if (pvt) 01748 pvt->sipoptions = profile; 01749 return profile; 01750 }
static int peer_status | ( | struct sip_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
Report Peer status in character string.
Definition at line 10036 of file chan_sip.c.
References ast_copy_string(), sip_peer::lastms, and sip_peer::maxms.
10037 { 10038 int res = 0; 10039 if (peer->maxms) { 10040 if (peer->lastms < 0) { 10041 ast_copy_string(status, "UNREACHABLE", statuslen); 10042 } else if (peer->lastms > peer->maxms) { 10043 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 10044 res = 1; 10045 } else if (peer->lastms) { 10046 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 10047 res = 1; 10048 } else { 10049 ast_copy_string(status, "UNKNOWN", statuslen); 10050 } 10051 } else { 10052 ast_copy_string(status, "Unmonitored", statuslen); 10053 /* Checking if port is 0 */ 10054 res = -1; 10055 } 10056 return res; 10057 }
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 10504 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().
10505 { 10506 int x, codec; 10507 10508 for(x = 0; x < 32 ; x++) { 10509 codec = ast_codec_pref_index(pref, x); 10510 if (!codec) 10511 break; 10512 ast_cli(fd, "%s", ast_getformatname(codec)); 10513 ast_cli(fd, ":%d", pref->framing[x]); 10514 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 10515 ast_cli(fd, ","); 10516 } 10517 if (!x) 10518 ast_cli(fd, "none"); 10519 }
static void print_group | ( | int | fd, | |
ast_group_t | group, | |||
int | crlf | |||
) | [static] |
Print call group and pickup group.
Definition at line 10295 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
10296 { 10297 char buf[256]; 10298 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 10299 }
static void process_request_queue | ( | struct sip_pvt * | p, | |
int * | recount, | |||
int * | nounlock | |||
) | [static] |
Definition at line 15981 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().
15982 { 15983 struct sip_request *req; 15984 15985 while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) { 15986 if (handle_request(p, req, &p->recv, recount, nounlock) == -1) { 15987 /* Request failed */ 15988 if (option_debug) { 15989 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 15990 } 15991 } 15992 ast_free(req); 15993 } 15994 }
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 5115 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.
05116 { 05117 const char *m; /* SDP media offer */ 05118 const char *c; 05119 const char *a; 05120 char host[258]; 05121 int len = -1; 05122 int portno = -1; /*!< RTP Audio port number */ 05123 int vportno = -1; /*!< RTP Video port number */ 05124 int udptlportno = -1; 05125 int peert38capability = 0; 05126 char s[256]; 05127 int old = 0; 05128 05129 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 05130 int peercapability = 0, peernoncodeccapability = 0; 05131 int vpeercapability = 0, vpeernoncodeccapability = 0; 05132 struct sockaddr_in sin; /*!< media socket address */ 05133 struct sockaddr_in vsin; /*!< Video socket address */ 05134 05135 const char *codecs; 05136 struct hostent *hp; /*!< RTP Audio host IP */ 05137 struct hostent *vhp = NULL; /*!< RTP video host IP */ 05138 struct ast_hostent audiohp; 05139 struct ast_hostent videohp; 05140 int codec; 05141 int destiterator = 0; 05142 int iterator; 05143 int sendonly = -1; 05144 int numberofports; 05145 struct ast_rtp *newaudiortp, *newvideortp; /* Buffers for codec handling */ 05146 int newjointcapability; /* Negotiated capability */ 05147 int newpeercapability; 05148 int newnoncodeccapability; 05149 int numberofmediastreams = 0; 05150 int debug = sip_debug_test_pvt(p); 05151 05152 int found_rtpmap_codecs[SDP_MAX_RTPMAP_CODECS]; 05153 int last_rtpmap_codec=0; 05154 05155 if (!p->rtp) { 05156 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 05157 return -1; 05158 } 05159 05160 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 05161 #ifdef LOW_MEMORY 05162 newaudiortp = ast_threadstorage_get(&ts_audio_rtp, ast_rtp_alloc_size()); 05163 #else 05164 newaudiortp = alloca(ast_rtp_alloc_size()); 05165 #endif 05166 memset(newaudiortp, 0, ast_rtp_alloc_size()); 05167 ast_rtp_new_init(newaudiortp); 05168 ast_rtp_pt_clear(newaudiortp); 05169 05170 #ifdef LOW_MEMORY 05171 newvideortp = ast_threadstorage_get(&ts_video_rtp, ast_rtp_alloc_size()); 05172 #else 05173 newvideortp = alloca(ast_rtp_alloc_size()); 05174 #endif 05175 memset(newvideortp, 0, ast_rtp_alloc_size()); 05176 ast_rtp_new_init(newvideortp); 05177 ast_rtp_pt_clear(newvideortp); 05178 05179 /* Update our last rtprx when we receive an SDP, too */ 05180 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 05181 05182 05183 /* Try to find first media stream */ 05184 m = get_sdp(req, "m"); 05185 destiterator = req->sdp_start; 05186 c = get_sdp_iterate(&destiterator, req, "c"); 05187 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 05188 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 05189 return -1; 05190 } 05191 05192 /* Check for IPv4 address (not IPv6 yet) */ 05193 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05194 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 05195 return -1; 05196 } 05197 05198 /* XXX This could block for a long time, and block the main thread! XXX */ 05199 hp = ast_gethostbyname(host, &audiohp); 05200 if (!hp) { 05201 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 05202 return -1; 05203 } 05204 vhp = hp; /* Copy to video address as default too */ 05205 05206 iterator = req->sdp_start; 05207 ast_set_flag(&p->flags[0], SIP_NOVIDEO); 05208 05209 05210 /* Find media streams in this SDP offer */ 05211 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 05212 int x; 05213 int audio = FALSE; 05214 05215 numberofports = 1; 05216 len = -1; 05217 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05218 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1 && len > 0)) { 05219 audio = TRUE; 05220 numberofmediastreams++; 05221 /* Found audio stream in this media definition */ 05222 portno = x; 05223 /* Scan through the RTP payload types specified in a "m=" line: */ 05224 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05225 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05226 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05227 return -1; 05228 } 05229 if (debug) 05230 ast_verbose("Found RTP audio format %d\n", codec); 05231 ast_rtp_set_m_type(newaudiortp, codec); 05232 } 05233 } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) || 05234 (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1 && len >= 0)) { 05235 /* If it is not audio - is it video ? */ 05236 ast_clear_flag(&p->flags[0], SIP_NOVIDEO); 05237 numberofmediastreams++; 05238 vportno = x; 05239 /* Scan through the RTP payload types specified in a "m=" line: */ 05240 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 05241 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 05242 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 05243 return -1; 05244 } 05245 if (debug) 05246 ast_verbose("Found RTP video format %d\n", codec); 05247 ast_rtp_set_m_type(newvideortp, codec); 05248 } 05249 } else if (p->udptl && ( (sscanf(m, "image %d udptl t38%n", &x, &len) == 1 && len > 0) || 05250 (sscanf(m, "image %d UDPTL t38%n", &x, &len) == 1 && len >= 0) )) { 05251 if (debug) 05252 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 05253 udptlportno = x; 05254 numberofmediastreams++; 05255 05256 if (p->owner && p->lastinvite) { 05257 p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ 05258 if (option_debug > 1) 05259 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); 05260 } else { 05261 p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ 05262 if (option_debug > 1) 05263 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05264 } 05265 } else 05266 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 05267 if (numberofports > 1) 05268 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 05269 05270 05271 /* Check for Media-description-level-address for audio */ 05272 c = get_sdp_iterate(&destiterator, req, "c"); 05273 if (!ast_strlen_zero(c)) { 05274 if (sscanf(c, "IN IP4 %256s", host) != 1) { 05275 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 05276 } else { 05277 /* XXX This could block for a long time, and block the main thread! XXX */ 05278 if (audio) { 05279 if ( !(hp = ast_gethostbyname(host, &audiohp))) { 05280 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c); 05281 return -2; 05282 } 05283 } else if (!(vhp = ast_gethostbyname(host, &videohp))) { 05284 ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c); 05285 return -2; 05286 } 05287 } 05288 05289 } 05290 } 05291 if (portno == -1 && vportno == -1 && udptlportno == -1) 05292 /* No acceptable offer found in SDP - we have no ports */ 05293 /* Do not change RTP or VRTP if this is a re-invite */ 05294 return -2; 05295 05296 if (numberofmediastreams > 2) 05297 /* We have too many fax, audio and/or video media streams, fail this offer */ 05298 return -3; 05299 05300 /* RTP addresses and ports for audio and video */ 05301 sin.sin_family = AF_INET; 05302 vsin.sin_family = AF_INET; 05303 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 05304 if (vhp) 05305 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 05306 05307 /* Setup UDPTL port number */ 05308 if (p->udptl) { 05309 if (udptlportno > 0) { 05310 sin.sin_port = htons(udptlportno); 05311 if (ast_test_flag(&p->flags[0], SIP_NAT) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) { 05312 struct sockaddr_in peer; 05313 ast_rtp_get_peer(p->rtp, &peer); 05314 if (peer.sin_addr.s_addr) { 05315 memcpy(&sin.sin_addr, &peer.sin_addr, sizeof(sin.sin_addr)); 05316 if (debug) { 05317 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)); 05318 } 05319 } 05320 } 05321 ast_udptl_set_peer(p->udptl, &sin); 05322 if (debug) 05323 ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05324 } else { 05325 ast_udptl_stop(p->udptl); 05326 if (debug) 05327 ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n"); 05328 } 05329 } 05330 05331 05332 if (p->rtp) { 05333 if (portno > 0) { 05334 sin.sin_port = htons(portno); 05335 ast_rtp_set_peer(p->rtp, &sin); 05336 if (debug) 05337 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05338 } else { 05339 if (udptlportno > 0) { 05340 if (debug) 05341 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session. Callid %s\n", p->callid); 05342 } else { 05343 ast_rtp_stop(p->rtp); 05344 if (debug) 05345 ast_verbose("Peer doesn't provide audio. Callid %s\n", p->callid); 05346 } 05347 } 05348 } 05349 /* Setup video port number */ 05350 if (vportno != -1) 05351 vsin.sin_port = htons(vportno); 05352 05353 /* Next, scan through each "a=rtpmap:" line, noting each 05354 * specified RTP payload type (with corresponding MIME subtype): 05355 */ 05356 /* XXX This needs to be done per media stream, since it's media stream specific */ 05357 iterator = req->sdp_start; 05358 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05359 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 05360 if (option_debug > 1) { 05361 int breakout = FALSE; 05362 05363 /* If we're debugging, check for unsupported sdp options */ 05364 if (!strncasecmp(a, "rtcp:", (size_t) 5)) { 05365 if (debug) 05366 ast_verbose("Got unsupported a:rtcp in SDP offer \n"); 05367 breakout = TRUE; 05368 } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) { 05369 /* Format parameters: Not supported */ 05370 /* Note: This is used for codec parameters, like bitrate for 05371 G722 and video formats for H263 and H264 05372 See RFC2327 for an example */ 05373 if (debug) 05374 ast_verbose("Got unsupported a:fmtp in SDP offer \n"); 05375 breakout = TRUE; 05376 } else if (!strncasecmp(a, "framerate:", (size_t) 10)) { 05377 /* Video stuff: Not supported */ 05378 if (debug) 05379 ast_verbose("Got unsupported a:framerate in SDP offer \n"); 05380 breakout = TRUE; 05381 } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) { 05382 /* Video stuff: Not supported */ 05383 if (debug) 05384 ast_verbose("Got unsupported a:maxprate in SDP offer \n"); 05385 breakout = TRUE; 05386 } else if (!strncasecmp(a, "crypto:", (size_t) 7)) { 05387 /* SRTP stuff, not yet supported */ 05388 if (debug) 05389 ast_verbose("Got unsupported a:crypto in SDP offer \n"); 05390 breakout = TRUE; 05391 } 05392 if (breakout) /* We have a match, skip to next header */ 05393 continue; 05394 } 05395 if (!strcasecmp(a, "sendonly")) { 05396 if (sendonly == -1) 05397 sendonly = 1; 05398 continue; 05399 } else if (!strcasecmp(a, "inactive")) { 05400 if (sendonly == -1) 05401 sendonly = 2; 05402 continue; 05403 } else if (!strcasecmp(a, "sendrecv")) { 05404 if (sendonly == -1) 05405 sendonly = 0; 05406 continue; 05407 } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 05408 char *tmp = strrchr(a, ':'); 05409 long int framing = 0; 05410 if (tmp) { 05411 tmp++; 05412 framing = strtol(tmp, NULL, 10); 05413 if (framing == LONG_MIN || framing == LONG_MAX) { 05414 framing = 0; 05415 if (option_debug) 05416 ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a); 05417 } 05418 } 05419 if (framing && p->autoframing) { 05420 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 05421 int codec_n; 05422 int format = 0; 05423 for (codec_n = 0; codec_n < MAX_RTP_PT; codec_n++) { 05424 format = ast_rtp_codec_getformat(codec_n); 05425 if (!format) /* non-codec or not found */ 05426 continue; 05427 if (option_debug) 05428 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 05429 ast_codec_pref_setsize(pref, format, framing); 05430 } 05431 ast_rtp_codec_setpref(p->rtp, pref); 05432 } 05433 continue; 05434 } else if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) == 2) { 05435 /* We have a rtpmap to handle */ 05436 int found = FALSE; 05437 /* We should propably check if this is an audio or video codec 05438 so we know where to look */ 05439 05440 if (last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) { 05441 /* Note: should really look at the 'freq' and '#chans' params too */ 05442 if(ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 05443 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) { 05444 if (debug) 05445 ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec); 05446 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05447 last_rtpmap_codec++; 05448 found = TRUE; 05449 05450 } else if (p->vrtp) { 05451 if(ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) { 05452 if (debug) 05453 ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec); 05454 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05455 last_rtpmap_codec++; 05456 found = TRUE; 05457 } 05458 } 05459 } else { 05460 if (debug) 05461 ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec); 05462 } 05463 05464 if (!found) { 05465 /* Remove this codec since it's an unknown media type for us */ 05466 /* XXX This is buggy since the media line for audio and video can have the 05467 same numbers. We need to check as described above, but for testing this works... */ 05468 ast_rtp_unset_m_type(newaudiortp, codec); 05469 ast_rtp_unset_m_type(newvideortp, codec); 05470 if (debug) 05471 ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec); 05472 } 05473 } 05474 } 05475 05476 if (udptlportno != -1) { 05477 int found = 0, x; 05478 05479 old = 0; 05480 05481 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 05482 iterator = req->sdp_start; 05483 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05484 if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) { 05485 found = 1; 05486 if (option_debug > 2) 05487 ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x); 05488 } else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1) || (sscanf(a, "T38FaxMaxRate:%d", &x) == 1)) { 05489 found = 1; 05490 if (option_debug > 2) 05491 ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x); 05492 switch (x) { 05493 case 14400: 05494 peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05495 break; 05496 case 12000: 05497 peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05498 break; 05499 case 9600: 05500 peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05501 break; 05502 case 7200: 05503 peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05504 break; 05505 case 4800: 05506 peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 05507 break; 05508 case 2400: 05509 peert38capability |= T38FAX_RATE_2400; 05510 break; 05511 } 05512 } else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) { 05513 found = 1; 05514 if (option_debug > 2) 05515 ast_log(LOG_DEBUG, "FaxVersion: %d\n",x); 05516 if (x == 0) 05517 peert38capability |= T38FAX_VERSION_0; 05518 else if (x == 1) 05519 peert38capability |= T38FAX_VERSION_1; 05520 } else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1) || (sscanf(a, "T38MaxDatagram:%d", &x) == 1)) { 05521 found = 1; 05522 if (option_debug > 2) 05523 ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x); 05524 ast_udptl_set_far_max_datagram(p->udptl, x); 05525 ast_udptl_set_local_max_datagram(p->udptl, x); 05526 } else if ((strncmp(a, "T38FaxFillBitRemoval", 20) == 0)) { 05527 found = 1; 05528 if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) { 05529 if (option_debug > 2) 05530 ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x); 05531 if (x == 1) 05532 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05533 } else { 05534 if (option_debug > 2) 05535 ast_log(LOG_DEBUG, "FillBitRemoval\n"); 05536 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05537 } 05538 } else if ((strncmp(a, "T38FaxTranscodingMMR", 20) == 0)) { 05539 found = 1; 05540 if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) { 05541 if (option_debug > 2) 05542 ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x); 05543 if (x == 1) 05544 peert38capability |= T38FAX_TRANSCODING_MMR; 05545 } else { 05546 if (option_debug > 2) 05547 ast_log(LOG_DEBUG, "Transcoding MMR\n"); 05548 peert38capability |= T38FAX_TRANSCODING_MMR; 05549 } 05550 } else if ((strncmp(a, "T38FaxTranscodingJBIG", 21) == 0)) { 05551 found = 1; 05552 if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) { 05553 if (option_debug > 2) 05554 ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x); 05555 if (x == 1) 05556 peert38capability |= T38FAX_TRANSCODING_JBIG; 05557 } else { 05558 if (option_debug > 2) 05559 ast_log(LOG_DEBUG, "Transcoding JBIG\n"); 05560 peert38capability |= T38FAX_TRANSCODING_JBIG; 05561 } 05562 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 05563 found = 1; 05564 if (option_debug > 2) 05565 ast_log(LOG_DEBUG, "RateManagement: %s\n", s); 05566 if (!strcasecmp(s, "localTCF")) 05567 peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 05568 else if (!strcasecmp(s, "transferredTCF")) 05569 peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 05570 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 05571 found = 1; 05572 if (option_debug > 2) 05573 ast_log(LOG_DEBUG, "UDP EC: %s\n", s); 05574 if (!strcasecmp(s, "t38UDPRedundancy")) { 05575 peert38capability |= T38FAX_UDP_EC_REDUNDANCY; 05576 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 05577 } else if (!strcasecmp(s, "t38UDPFEC")) { 05578 peert38capability |= T38FAX_UDP_EC_FEC; 05579 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 05580 } else { 05581 peert38capability |= T38FAX_UDP_EC_NONE; 05582 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05583 } 05584 } 05585 } 05586 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 05587 p->t38.peercapability = peert38capability; 05588 p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */ 05589 peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 05590 p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */ 05591 } 05592 if (debug) 05593 ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 05594 p->t38.capability, 05595 p->t38.peercapability, 05596 p->t38.jointcapability); 05597 } else { 05598 p->t38.state = T38_DISABLED; 05599 if (option_debug > 2) 05600 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05601 } 05602 05603 /* Now gather all of the codecs that we are asked for: */ 05604 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 05605 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 05606 05607 newjointcapability = p->capability & (peercapability | vpeercapability); 05608 newpeercapability = (peercapability | vpeercapability); 05609 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 05610 05611 05612 if (debug) { 05613 /* shame on whoever coded this.... */ 05614 char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE]; 05615 05616 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 05617 ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability), 05618 ast_getformatname_multiple(s2, SIPBUFSIZE, newpeercapability), 05619 ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability), 05620 ast_getformatname_multiple(s4, SIPBUFSIZE, newjointcapability)); 05621 05622 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 05623 ast_rtp_lookup_mime_multiple(s1, SIPBUFSIZE, p->noncodeccapability, 0, 0), 05624 ast_rtp_lookup_mime_multiple(s2, SIPBUFSIZE, peernoncodeccapability, 0, 0), 05625 ast_rtp_lookup_mime_multiple(s3, SIPBUFSIZE, newnoncodeccapability, 0, 0)); 05626 } 05627 if (!newjointcapability) { 05628 /* If T.38 was not negotiated either, totally bail out... */ 05629 if (!p->t38.jointcapability || !udptlportno) { 05630 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 05631 /* Do NOT Change current setting */ 05632 return -1; 05633 } else { 05634 if (option_debug > 2) 05635 ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n"); 05636 return 0; 05637 } 05638 } 05639 05640 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 05641 they are acceptable */ 05642 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 05643 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 05644 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 05645 05646 ast_rtp_pt_copy(p->rtp, newaudiortp); 05647 if (p->vrtp) 05648 ast_rtp_pt_copy(p->vrtp, newvideortp); 05649 05650 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 05651 ast_clear_flag(&p->flags[0], SIP_DTMF); 05652 if (newnoncodeccapability & AST_RTP_DTMF) { 05653 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 05654 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 05655 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 05656 ast_rtp_setdtmf(p->rtp, 1); 05657 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05658 } else { 05659 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 05660 } 05661 } 05662 05663 /* Setup audio port number */ 05664 if (p->rtp && sin.sin_port) { 05665 ast_rtp_set_peer(p->rtp, &sin); 05666 if (debug) 05667 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05668 } 05669 05670 /* Setup video port number */ 05671 if (p->vrtp && vsin.sin_port) { 05672 ast_rtp_set_peer(p->vrtp, &vsin); 05673 if (debug) 05674 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 05675 } 05676 05677 /* Ok, we're going with this offer */ 05678 if (option_debug > 1) { 05679 char buf[SIPBUFSIZE]; 05680 ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability)); 05681 } 05682 05683 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 05684 return 0; 05685 05686 if (option_debug > 3) 05687 ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n"); 05688 05689 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05690 if (debug) { 05691 char s1[SIPBUFSIZE], s2[SIPBUFSIZE]; 05692 ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 05693 ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability), 05694 ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats)); 05695 } 05696 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); 05697 ast_set_read_format(p->owner, p->owner->readformat); 05698 ast_set_write_format(p->owner, p->owner->writeformat); 05699 } 05700 05701 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 05702 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 05703 /* Activate a re-invite */ 05704 ast_queue_frame(p->owner, &ast_null_frame); 05705 } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { 05706 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 05707 S_OR(p->mohsuggest, NULL), 05708 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 05709 if (sendonly) 05710 ast_rtp_stop(p->rtp); 05711 /* RTCP needs to go ahead, even if we're on hold!!! */ 05712 /* Activate a re-invite */ 05713 ast_queue_frame(p->owner, &ast_null_frame); 05714 } 05715 05716 /* Manager Hold and Unhold events must be generated, if necessary */ 05717 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) 05718 change_hold_state(p, req, FALSE, sendonly); 05719 else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) 05720 change_hold_state(p, req, TRUE, sendonly); 05721 return 0; 05722 }
static int queue_request | ( | struct sip_pvt * | p, | |
const struct sip_request * | req | |||
) | [static] |
Definition at line 16046 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().
16047 { 16048 struct sip_request *newreq; 16049 16050 if (!(newreq = ast_calloc(1, sizeof(*newreq)))) { 16051 return -1; 16052 } 16053 16054 copy_request(newreq, req); 16055 AST_LIST_INSERT_TAIL(&p->request_queue, newreq, next); 16056 if (p->request_queue_sched_id == -1) { 16057 p->request_queue_sched_id = ast_sched_add(sched, 10, scheduler_process_request_queue, p); 16058 } 16059 16060 return 0; 16061 }
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 2532 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.
02533 { 02534 struct sip_peer *peer=NULL; 02535 struct ast_variable *var = NULL; 02536 struct ast_config *peerlist = NULL; 02537 struct ast_variable *tmp; 02538 struct ast_flags flags = {0}; 02539 const char *iabuf = NULL; 02540 char portstring[6]; /*up to five digits plus null terminator*/ 02541 const char *insecure; 02542 char *cat = NULL; 02543 unsigned short portnum; 02544 02545 /* First check on peer name */ 02546 if (newpeername) { 02547 var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL); 02548 if (!var && sin) 02549 var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02550 if (!var) { 02551 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 02552 /*!\note 02553 * If this one loaded something, then we need to ensure that the host 02554 * field matched. The only reason why we can't have this as a criteria 02555 * is because we only have the IP address and the host field might be 02556 * set as a name (and the reverse PTR might not match). 02557 */ 02558 if (var && sin) { 02559 for (tmp = var; tmp; tmp = tmp->next) { 02560 if (!strcasecmp(tmp->name, "host")) { 02561 struct hostent *hp; 02562 struct ast_hostent ahp; 02563 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 02564 /* No match */ 02565 ast_variables_destroy(var); 02566 var = NULL; 02567 } 02568 break; 02569 } 02570 } 02571 } 02572 } 02573 } 02574 02575 if (!var && sin) { /* Then check on IP address */ 02576 iabuf = ast_inet_ntoa(sin->sin_addr); 02577 portnum = ntohs(sin->sin_port); 02578 sprintf(portstring, "%d", portnum); 02579 var = ast_load_realtime("sippeers", "host", iabuf, "port", portstring, NULL); /* First check for fixed IP hosts */ 02580 if (!var) 02581 var = ast_load_realtime("sippeers", "ipaddr", iabuf, "port", portstring, NULL); /* Then check for registered hosts */ 02582 if (!var) { 02583 peerlist = ast_load_realtime_multientry("sippeers", "host", iabuf, NULL); /*No exact match, see if port is insecure, try host match first*/ 02584 if(peerlist){ 02585 while((cat = ast_category_browse(peerlist, cat))) 02586 { 02587 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02588 set_insecure_flags(&flags, insecure, -1); 02589 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02590 var = ast_category_root(peerlist, cat); 02591 break; 02592 } 02593 } 02594 } 02595 if(!var) { 02596 ast_config_destroy(peerlist); 02597 peerlist = NULL; /*for safety's sake*/ 02598 cat = NULL; 02599 peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", iabuf, NULL); /*No exact match, see if port is insecure, now try ip address match*/ 02600 if(peerlist) { 02601 while((cat = ast_category_browse(peerlist, cat))) 02602 { 02603 insecure = ast_variable_retrieve(peerlist, cat, "insecure"); 02604 set_insecure_flags(&flags, insecure, -1); 02605 if(ast_test_flag(&flags, SIP_INSECURE_PORT)) { 02606 var = ast_category_root(peerlist, cat); 02607 break; 02608 } 02609 } 02610 } 02611 } 02612 } 02613 } 02614 02615 if (!var) { 02616 if(peerlist) 02617 ast_config_destroy(peerlist); 02618 return NULL; 02619 } 02620 02621 for (tmp = var; tmp; tmp = tmp->next) { 02622 /* If this is type=user, then skip this object. */ 02623 if (!strcasecmp(tmp->name, "type") && 02624 !strcasecmp(tmp->value, "user")) { 02625 ast_variables_destroy(var); 02626 return NULL; 02627 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 02628 newpeername = tmp->value; 02629 } 02630 } 02631 02632 if (!newpeername) { /* Did not find peer in realtime */ 02633 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", iabuf); 02634 if(peerlist) 02635 ast_config_destroy(peerlist); 02636 else 02637 ast_variables_destroy(var); 02638 return NULL; 02639 } 02640 02641 /* Peer found in realtime, now build it in memory */ 02642 peer = build_peer(newpeername, var, NULL, 1); 02643 if (!peer) { 02644 if(peerlist) 02645 ast_config_destroy(peerlist); 02646 else 02647 ast_variables_destroy(var); 02648 return NULL; 02649 } 02650 02651 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) { 02652 /* Cache peer */ 02653 ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 02654 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 02655 if (!AST_SCHED_DEL(sched, peer->expire)) { 02656 struct sip_peer *peer_ptr = peer; 02657 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02658 } 02659 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, ASTOBJ_REF(peer)); 02660 if (peer->expire == -1) { 02661 struct sip_peer *peer_ptr = peer; 02662 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 02663 } 02664 } 02665 ASTOBJ_CONTAINER_LINK(&peerl,peer); 02666 } 02667 ast_set_flag(&peer->flags[0], SIP_REALTIME); 02668 if(peerlist) 02669 ast_config_destroy(peerlist); 02670 else 02671 ast_variables_destroy(var); 02672 return peer; 02673 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
const char * | username, | |||
const char * | fullcontact, | |||
int | expirey | |||
) | [static] |
Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups.
Definition at line 2418 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.
02419 { 02420 char port[10]; 02421 char ipaddr[INET_ADDRSTRLEN]; 02422 char regseconds[20]; 02423 02424 char *sysname = ast_config_AST_SYSTEM_NAME; 02425 char *syslabel = NULL; 02426 02427 time_t nowtime = time(NULL) + expirey; 02428 const char *fc = fullcontact ? "fullcontact" : NULL; 02429 02430 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 02431 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 02432 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02433 02434 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 02435 sysname = NULL; 02436 else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME)) 02437 syslabel = "regserver"; 02438 02439 if (fc) 02440 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02441 "port", port, "regseconds", regseconds, 02442 "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */ 02443 else 02444 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02445 "port", port, "regseconds", regseconds, 02446 "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */ 02447 }
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 2723 of file chan_sip.c.
References ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, ast_variable::value, and var.
02724 { 02725 struct ast_variable *var; 02726 struct ast_variable *tmp; 02727 struct sip_user *user = NULL; 02728 02729 var = ast_load_realtime("sipusers", "name", username, NULL); 02730 02731 if (!var) 02732 return NULL; 02733 02734 for (tmp = var; tmp; tmp = tmp->next) { 02735 if (!strcasecmp(tmp->name, "type") && 02736 !strcasecmp(tmp->value, "peer")) { 02737 ast_variables_destroy(var); 02738 return NULL; 02739 } 02740 } 02741 02742 user = build_user(username, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02743 02744 if (!user) { /* No user found */ 02745 ast_variables_destroy(var); 02746 return NULL; 02747 } 02748 02749 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02750 ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02751 suserobjs++; 02752 ASTOBJ_CONTAINER_LINK(&userl,user); 02753 } else { 02754 /* Move counter from s to r... */ 02755 suserobjs--; 02756 ruserobjs++; 02757 } 02758 ast_set_flag(&user->flags[0], SIP_REALTIME); 02759 ast_variables_destroy(var); 02760 return user; 02761 }
static void receive_message | ( | struct sip_pvt * | p, | |
struct sip_request * | req | |||
) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 9919 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().
09920 { 09921 char buf[1024]; 09922 struct ast_frame f; 09923 const char *content_type = get_header(req, "Content-Type"); 09924 09925 if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */ 09926 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 09927 if (!p->owner) 09928 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09929 return; 09930 } 09931 09932 if (get_msg_text(buf, sizeof(buf), req)) { 09933 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 09934 transmit_response(p, "202 Accepted", req); 09935 if (!p->owner) 09936 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09937 return; 09938 } 09939 09940 if (p->owner) { 09941 if (sip_debug_test_pvt(p)) 09942 ast_verbose("Message received: '%s'\n", buf); 09943 memset(&f, 0, sizeof(f)); 09944 f.frametype = AST_FRAME_TEXT; 09945 f.subclass = 0; 09946 f.offset = 0; 09947 f.data = buf; 09948 f.datalen = strlen(buf); 09949 ast_queue_frame(p->owner, &f); 09950 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 09951 } else { /* Message outside of a call, we do not support that */ 09952 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); 09953 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 09954 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09955 } 09956 return; 09957 }
static char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 1644 of file chan_sip.c.
References referstatusstrings, and text.
Referenced by __sip_show_channels().
01645 { 01646 int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0])); 01647 int x; 01648 01649 for (x = 0; x < i; x++) { 01650 if (referstatusstrings[x].status == rstatus) 01651 return (char *) referstatusstrings[x].text; 01652 } 01653 return ""; 01654 }
static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 8109 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.
08110 { 08111 char data[256]; 08112 struct in_addr in; 08113 int expiry; 08114 int port; 08115 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 08116 08117 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 08118 return; 08119 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 08120 return; 08121 08122 scan = data; 08123 addr = strsep(&scan, ":"); 08124 port_str = strsep(&scan, ":"); 08125 expiry_str = strsep(&scan, ":"); 08126 username = strsep(&scan, ":"); 08127 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 08128 08129 if (!inet_aton(addr, &in)) 08130 return; 08131 08132 if (port_str) 08133 port = atoi(port_str); 08134 else 08135 return; 08136 08137 if (expiry_str) 08138 expiry = atoi(expiry_str); 08139 else 08140 return; 08141 08142 if (username) 08143 ast_copy_string(peer->username, username, sizeof(peer->username)); 08144 if (contact) 08145 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 08146 08147 if (option_debug > 1) 08148 ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 08149 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 08150 08151 memset(&peer->addr, 0, sizeof(peer->addr)); 08152 peer->addr.sin_family = AF_INET; 08153 peer->addr.sin_addr = in; 08154 peer->addr.sin_port = htons(port); 08155 if (sipsock < 0) { 08156 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 08157 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 08158 struct sip_peer *peer_ptr = peer; 08159 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08160 } 08161 peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, ASTOBJ_REF(peer)); 08162 if (peer->pokeexpire == -1) { 08163 struct sip_peer *peer_ptr = peer; 08164 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08165 } 08166 } else 08167 sip_poke_peer(peer); 08168 if (!AST_SCHED_DEL(sched, peer->expire)) { 08169 struct sip_peer *peer_ptr = peer; 08170 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08171 } 08172 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, ASTOBJ_REF(peer)); 08173 if (peer->expire == -1) { 08174 struct sip_peer *peer_ptr = peer; 08175 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 08176 } 08177 register_peer_exten(peer, TRUE); 08178 }
static void register_peer_exten | ( | struct sip_peer * | peer, | |
int | onoff | |||
) | [static] |
Automatically add peer extension to dial plan.
Definition at line 2450 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.
02451 { 02452 char multi[256]; 02453 char *stringp, *ext, *context; 02454 02455 /* XXX note that global_regcontext is both a global 'enable' flag and 02456 * the name of the global regexten context, if not specified 02457 * individually. 02458 */ 02459 if (ast_strlen_zero(global_regcontext)) 02460 return; 02461 02462 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 02463 stringp = multi; 02464 while ((ext = strsep(&stringp, "&"))) { 02465 if ((context = strchr(ext, '@'))) { 02466 *context++ = '\0'; /* split ext@context */ 02467 if (!ast_context_find(context)) { 02468 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 02469 continue; 02470 } 02471 } else { 02472 context = global_regcontext; 02473 } 02474 if (onoff) { 02475 if (!ast_exists_extension(NULL, context, ext, 1, NULL)) { 02476 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 02477 ast_strdup(peer->name), ast_free, "SIP"); 02478 } 02479 } else { 02480 ast_context_remove_extension(context, ext, 1, NULL); 02481 } 02482 } 02483 }
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 8825 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.
08827 { 08828 enum check_auth_result res = AUTH_NOT_FOUND; 08829 struct sip_peer *peer; 08830 char tmp[256]; 08831 char *name, *c; 08832 char *t; 08833 char *domain; 08834 08835 /* Terminate URI */ 08836 t = uri; 08837 while(*t && (*t > 32) && (*t != ';')) 08838 t++; 08839 *t = '\0'; 08840 08841 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 08842 if (pedanticsipchecking) 08843 ast_uri_decode(tmp); 08844 08845 c = get_in_brackets(tmp); 08846 c = strsep(&c, ";"); /* Ditch ;user=phone */ 08847 08848 if (!strncasecmp(c, "sip:", 4)) { 08849 name = c + 4; 08850 } else { 08851 name = c; 08852 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 08853 } 08854 08855 /* Strip off the domain name */ 08856 if ((c = strchr(name, '@'))) { 08857 *c++ = '\0'; 08858 domain = c; 08859 if ((c = strchr(domain, ':'))) /* Remove :port */ 08860 *c = '\0'; 08861 if (!AST_LIST_EMPTY(&domain_list)) { 08862 if (!check_sip_domain(domain, NULL, 0)) { 08863 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 08864 return AUTH_UNKNOWN_DOMAIN; 08865 } 08866 } 08867 } 08868 08869 ast_string_field_set(p, exten, name); 08870 build_contact(p); 08871 peer = find_peer(name, NULL, 1, 0); 08872 if (!(peer && ast_apply_ha(peer->ha, sin))) { 08873 /* Peer fails ACL check */ 08874 if (peer) { 08875 ASTOBJ_UNREF(peer, sip_destroy_peer); 08876 res = AUTH_ACL_FAILED; 08877 } else 08878 res = AUTH_NOT_FOUND; 08879 } 08880 if (peer) { 08881 /* Set Frame packetization */ 08882 if (p->rtp) { 08883 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 08884 p->autoframing = peer->autoframing; 08885 } 08886 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 08887 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 08888 res = AUTH_PEER_NOT_DYNAMIC; 08889 } else { 08890 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 08891 transmit_response(p, "100 Trying", req); 08892 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { 08893 if (sip_cancel_destroy(p)) 08894 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08895 08896 /* We have a succesful registration attemp with proper authentication, 08897 now, update the peer */ 08898 switch (parse_register_contact(p, peer, req)) { 08899 case PARSE_REGISTER_FAILED: 08900 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08901 transmit_response_with_date(p, "400 Bad Request", req); 08902 peer->lastmsgssent = -1; 08903 res = 0; 08904 break; 08905 case PARSE_REGISTER_QUERY: 08906 transmit_response_with_date(p, "200 OK", req); 08907 peer->lastmsgssent = -1; 08908 res = 0; 08909 break; 08910 case PARSE_REGISTER_UPDATE: 08911 update_peer(peer, p->expiry); 08912 /* Say OK and ask subsystem to retransmit msg counter */ 08913 transmit_response_with_date(p, "200 OK", req); 08914 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 08915 peer->lastmsgssent = -1; 08916 res = 0; 08917 break; 08918 } 08919 } 08920 } 08921 } 08922 if (!peer && autocreatepeer) { 08923 /* Create peer if we have autocreate mode enabled */ 08924 peer = temp_peer(name); 08925 if (peer) { 08926 ASTOBJ_CONTAINER_LINK(&peerl, peer); 08927 if (sip_cancel_destroy(p)) 08928 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 08929 switch (parse_register_contact(p, peer, req)) { 08930 case PARSE_REGISTER_FAILED: 08931 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08932 transmit_response_with_date(p, "400 Bad Request", req); 08933 peer->lastmsgssent = -1; 08934 res = 0; 08935 break; 08936 case PARSE_REGISTER_QUERY: 08937 transmit_response_with_date(p, "200 OK", req); 08938 peer->lastmsgssent = -1; 08939 res = 0; 08940 break; 08941 case PARSE_REGISTER_UPDATE: 08942 /* Say OK and ask subsystem to retransmit msg counter */ 08943 transmit_response_with_date(p, "200 OK", req); 08944 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08945 peer->lastmsgssent = -1; 08946 res = 0; 08947 break; 08948 } 08949 } 08950 } 08951 if (!res) { 08952 ast_device_state_changed("SIP/%s", peer->name); 08953 } 08954 if (res < 0) { 08955 switch (res) { 08956 case AUTH_SECRET_FAILED: 08957 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 08958 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08959 break; 08960 case AUTH_USERNAME_MISMATCH: 08961 /* Username and digest username does not match. 08962 Asterisk uses the From: username for authentication. We need the 08963 users to use the same authentication user name until we support 08964 proper authentication by digest auth name */ 08965 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 08966 break; 08967 case AUTH_NOT_FOUND: 08968 case AUTH_PEER_NOT_DYNAMIC: 08969 case AUTH_ACL_FAILED: 08970 if (global_alwaysauthreject) { 08971 transmit_fake_auth_response(p, &p->initreq, 1); 08972 } else { 08973 /* URI not found */ 08974 if (res == AUTH_PEER_NOT_DYNAMIC) 08975 transmit_response(p, "403 Forbidden", &p->initreq); 08976 else 08977 transmit_response(p, "404 Not found", &p->initreq); 08978 } 08979 break; 08980 default: 08981 break; 08982 } 08983 } 08984 if (peer) 08985 ASTOBJ_UNREF(peer, sip_destroy_peer); 08986 08987 return res; 08988 }
static char * regstate2str | ( | enum sipregistrystate | regstate | ) | const [static] |
Convert registration state status to string.
Definition at line 7586 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.
07587 { 07588 switch(regstate) { 07589 case REG_STATE_FAILED: 07590 return "Failed"; 07591 case REG_STATE_UNREGISTERED: 07592 return "Unregistered"; 07593 case REG_STATE_REGSENT: 07594 return "Request Sent"; 07595 case REG_STATE_AUTHSENT: 07596 return "Auth. Sent"; 07597 case REG_STATE_REGISTERED: 07598 return "Registered"; 07599 case REG_STATE_REJECTED: 07600 return "Rejected"; 07601 case REG_STATE_TIMEOUT: 07602 return "Timeout"; 07603 case REG_STATE_NOAUTH: 07604 return "No Authentication"; 07605 default: 07606 return "Unknown"; 07607 } 07608 }
static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 18673 of file chan_sip.c.
References sip_reload().
18674 { 18675 return sip_reload(0, 0, NULL); 18676 }
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 17552 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().
17553 { 17554 struct ast_config *cfg, *ucfg; 17555 struct ast_variable *v; 17556 struct sip_peer *peer; 17557 struct sip_user *user; 17558 struct ast_hostent ahp; 17559 char *cat, *stringp, *context, *oldregcontext; 17560 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 17561 struct hostent *hp; 17562 int format; 17563 struct ast_flags dummy[2]; 17564 int auto_sip_domains = FALSE; 17565 struct sockaddr_in old_bindaddr = bindaddr; 17566 int registry_count = 0, peer_count = 0, user_count = 0; 17567 unsigned int temp_tos = 0; 17568 struct ast_flags debugflag = {0}; 17569 17570 cfg = ast_config_load(config); 17571 17572 /* We *must* have a config file otherwise stop immediately */ 17573 if (!cfg) { 17574 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 17575 return -1; 17576 } 17577 17578 if (option_debug > 3) 17579 ast_log(LOG_DEBUG, "--------------- SIP reload started\n"); 17580 17581 clear_realm_authentication(authl); 17582 clear_sip_domains(); 17583 authl = NULL; 17584 17585 ast_free_ha(global_contact_ha); 17586 global_contact_ha = NULL; 17587 17588 /* First, destroy all outstanding registry calls */ 17589 /* This is needed, since otherwise active registry entries will not be destroyed */ 17590 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17591 ASTOBJ_RDLOCK(iterator); 17592 if (iterator->call) { 17593 if (option_debug > 2) 17594 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 17595 /* This will also remove references to the registry */ 17596 sip_destroy(iterator->call); 17597 } 17598 ASTOBJ_UNLOCK(iterator); 17599 17600 } while(0)); 17601 17602 /* Then, actually destroy users and registry */ 17603 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 17604 if (option_debug > 3) 17605 ast_log(LOG_DEBUG, "--------------- Done destroying user list\n"); 17606 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 17607 if (option_debug > 3) 17608 ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n"); 17609 ASTOBJ_CONTAINER_MARKALL(&peerl); 17610 17611 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 17612 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 17613 oldregcontext = oldcontexts; 17614 17615 /* Clear all flags before setting default values */ 17616 /* Preserve debugging settings for console */ 17617 ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 17618 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 17619 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 17620 ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE); 17621 17622 /* Reset IP addresses */ 17623 memset(&bindaddr, 0, sizeof(bindaddr)); 17624 ast_free_ha(localaddr); 17625 memset(&localaddr, 0, sizeof(localaddr)); 17626 memset(&externip, 0, sizeof(externip)); 17627 memset(&default_prefs, 0 , sizeof(default_prefs)); 17628 outboundproxyip.sin_port = htons(STANDARD_SIP_PORT); 17629 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 17630 ourport = STANDARD_SIP_PORT; 17631 srvlookup = DEFAULT_SRVLOOKUP; 17632 global_tos_sip = DEFAULT_TOS_SIP; 17633 global_tos_audio = DEFAULT_TOS_AUDIO; 17634 global_tos_video = DEFAULT_TOS_VIDEO; 17635 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 17636 externexpire = 0; /* Expiration for DNS re-issuing */ 17637 externrefresh = 10; 17638 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 17639 17640 /* Reset channel settings to default before re-configuring */ 17641 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 17642 global_regcontext[0] = '\0'; 17643 expiry = DEFAULT_EXPIRY; 17644 global_notifyringing = DEFAULT_NOTIFYRINGING; 17645 global_limitonpeers = FALSE; 17646 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 17647 global_notifyhold = FALSE; 17648 global_alwaysauthreject = 0; 17649 global_allowsubscribe = FALSE; 17650 ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent)); 17651 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 17652 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) 17653 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 17654 else 17655 ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm)); 17656 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 17657 compactheaders = DEFAULT_COMPACTHEADERS; 17658 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 17659 global_regattempts_max = 0; 17660 pedanticsipchecking = DEFAULT_PEDANTIC; 17661 global_mwitime = DEFAULT_MWITIME; 17662 autocreatepeer = DEFAULT_AUTOCREATEPEER; 17663 global_autoframing = 0; 17664 global_allowguest = DEFAULT_ALLOWGUEST; 17665 global_rtptimeout = 0; 17666 global_rtpholdtimeout = 0; 17667 global_rtpkeepalive = 0; 17668 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 17669 global_rtautoclear = 120; 17670 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 17671 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 17672 ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE); 17673 17674 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 17675 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 17676 default_subscribecontext[0] = '\0'; 17677 default_language[0] = '\0'; 17678 default_fromdomain[0] = '\0'; 17679 default_qualify = DEFAULT_QUALIFY; 17680 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 17681 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 17682 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 17683 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 17684 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 17685 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 17686 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 17687 17688 /* Debugging settings, always default to off */ 17689 dumphistory = FALSE; 17690 recordhistory = FALSE; 17691 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 17692 17693 /* Misc settings for the channel */ 17694 global_relaxdtmf = FALSE; 17695 global_callevents = FALSE; 17696 global_t1min = DEFAULT_T1MIN; 17697 17698 global_matchexterniplocally = FALSE; 17699 17700 /* Copy the default jb config over global_jbconf */ 17701 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 17702 17703 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 17704 17705 /* Read the [general] config section of sip.conf (or from realtime config) */ 17706 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 17707 if (handle_common_options(&global_flags[0], &dummy[0], v)) 17708 continue; 17709 /* handle jb conf */ 17710 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 17711 continue; 17712 17713 /* Create the interface list */ 17714 if (!strcasecmp(v->name, "context")) { 17715 ast_copy_string(default_context, v->value, sizeof(default_context)); 17716 } else if (!strcasecmp(v->name, "subscribecontext")) { 17717 ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext)); 17718 } else if (!strcasecmp(v->name, "allowguest")) { 17719 global_allowguest = ast_true(v->value) ? 1 : 0; 17720 } else if (!strcasecmp(v->name, "realm")) { 17721 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 17722 } else if (!strcasecmp(v->name, "useragent")) { 17723 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 17724 if (option_debug) 17725 ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 17726 } else if (!strcasecmp(v->name, "allowtransfer")) { 17727 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 17728 } else if (!strcasecmp(v->name, "rtcachefriends")) { 17729 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 17730 } else if (!strcasecmp(v->name, "rtsavesysname")) { 17731 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME); 17732 } else if (!strcasecmp(v->name, "rtupdate")) { 17733 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE); 17734 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 17735 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 17736 } else if (!strcasecmp(v->name, "t1min")) { 17737 global_t1min = atoi(v->value); 17738 } else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) { 17739 global_dynamic_exclude_static = ast_true(v->value); 17740 } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { 17741 global_contact_ha = ast_append_ha(v->name + 7, v->value, global_contact_ha); 17742 } else if (!strcasecmp(v->name, "rtautoclear")) { 17743 int i = atoi(v->value); 17744 if (i > 0) 17745 global_rtautoclear = i; 17746 else 17747 i = 0; 17748 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 17749 } else if (!strcasecmp(v->name, "usereqphone")) { 17750 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 17751 } else if (!strcasecmp(v->name, "relaxdtmf")) { 17752 global_relaxdtmf = ast_true(v->value); 17753 } else if (!strcasecmp(v->name, "checkmwi")) { 17754 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 17755 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 17756 global_mwitime = DEFAULT_MWITIME; 17757 } 17758 } else if (!strcasecmp(v->name, "vmexten")) { 17759 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 17760 } else if (!strcasecmp(v->name, "rtptimeout")) { 17761 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 17762 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17763 global_rtptimeout = 0; 17764 } 17765 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 17766 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 17767 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 17768 global_rtpholdtimeout = 0; 17769 } 17770 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 17771 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 17772 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 17773 global_rtpkeepalive = 0; 17774 } 17775 } else if (!strcasecmp(v->name, "compactheaders")) { 17776 compactheaders = ast_true(v->value); 17777 } else if (!strcasecmp(v->name, "notifymimetype")) { 17778 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 17779 } else if (!strncasecmp(v->name, "limitonpeer", 11)) { 17780 global_limitonpeers = ast_true(v->value); 17781 } else if (!strcasecmp(v->name, "directrtpsetup")) { 17782 global_directrtpsetup = ast_true(v->value); 17783 } else if (!strcasecmp(v->name, "notifyringing")) { 17784 global_notifyringing = ast_true(v->value); 17785 } else if (!strcasecmp(v->name, "notifyhold")) { 17786 global_notifyhold = ast_true(v->value); 17787 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 17788 global_alwaysauthreject = ast_true(v->value); 17789 } else if (!strcasecmp(v->name, "mohinterpret") 17790 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 17791 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 17792 } else if (!strcasecmp(v->name, "mohsuggest")) { 17793 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 17794 } else if (!strcasecmp(v->name, "language")) { 17795 ast_copy_string(default_language, v->value, sizeof(default_language)); 17796 } else if (!strcasecmp(v->name, "regcontext")) { 17797 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 17798 stringp = newcontexts; 17799 /* Let's remove any contexts that are no longer defined in regcontext */ 17800 cleanup_stale_contexts(stringp, oldregcontext); 17801 /* Create contexts if they don't exist already */ 17802 while ((context = strsep(&stringp, "&"))) { 17803 if (!ast_context_find(context)) 17804 ast_context_create(NULL, context,"SIP"); 17805 } 17806 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 17807 } else if (!strcasecmp(v->name, "callerid")) { 17808 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 17809 } else if (!strcasecmp(v->name, "fromdomain")) { 17810 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 17811 } else if (!strcasecmp(v->name, "outboundproxy")) { 17812 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 17813 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 17814 } else if (!strcasecmp(v->name, "outboundproxyport")) { 17815 /* Port needs to be after IP */ 17816 sscanf(v->value, "%d", &format); 17817 outboundproxyip.sin_port = htons(format); 17818 } else if (!strcasecmp(v->name, "autocreatepeer")) { 17819 autocreatepeer = ast_true(v->value); 17820 } else if (!strcasecmp(v->name, "srvlookup")) { 17821 srvlookup = ast_true(v->value); 17822 } else if (!strcasecmp(v->name, "pedantic")) { 17823 pedanticsipchecking = ast_true(v->value); 17824 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 17825 max_expiry = atoi(v->value); 17826 if (max_expiry < 1) 17827 max_expiry = DEFAULT_MAX_EXPIRY; 17828 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 17829 min_expiry = atoi(v->value); 17830 if (min_expiry < 1) 17831 min_expiry = DEFAULT_MIN_EXPIRY; 17832 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 17833 default_expiry = atoi(v->value); 17834 if (default_expiry < 1) 17835 default_expiry = DEFAULT_DEFAULT_EXPIRY; 17836 } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */ 17837 if (ast_true(v->value)) 17838 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 17839 } else if (!strcasecmp(v->name, "dumphistory")) { 17840 dumphistory = ast_true(v->value); 17841 } else if (!strcasecmp(v->name, "recordhistory")) { 17842 recordhistory = ast_true(v->value); 17843 } else if (!strcasecmp(v->name, "registertimeout")) { 17844 global_reg_timeout = atoi(v->value); 17845 if (global_reg_timeout < 1) 17846 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 17847 } else if (!strcasecmp(v->name, "registerattempts")) { 17848 global_regattempts_max = atoi(v->value); 17849 } else if (!strcasecmp(v->name, "bindaddr")) { 17850 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 17851 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 17852 } else { 17853 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 17854 } 17855 } else if (!strcasecmp(v->name, "localnet")) { 17856 struct ast_ha *na; 17857 if (!(na = ast_append_ha("d", v->value, localaddr))) 17858 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 17859 else 17860 localaddr = na; 17861 } else if (!strcasecmp(v->name, "localmask")) { 17862 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 17863 } else if (!strcasecmp(v->name, "externip")) { 17864 if (!(hp = ast_gethostbyname(v->value, &ahp))) 17865 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 17866 else 17867 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 17868 externexpire = 0; 17869 } else if (!strcasecmp(v->name, "externhost")) { 17870 ast_copy_string(externhost, v->value, sizeof(externhost)); 17871 if (!(hp = ast_gethostbyname(externhost, &ahp))) 17872 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 17873 else 17874 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 17875 externexpire = time(NULL); 17876 } else if (!strcasecmp(v->name, "externrefresh")) { 17877 if (sscanf(v->value, "%d", &externrefresh) != 1) { 17878 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 17879 externrefresh = 10; 17880 } 17881 } else if (!strcasecmp(v->name, "allow")) { 17882 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1); 17883 } else if (!strcasecmp(v->name, "disallow")) { 17884 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0); 17885 } else if (!strcasecmp(v->name, "autoframing")) { 17886 global_autoframing = ast_true(v->value); 17887 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 17888 allow_external_domains = ast_true(v->value); 17889 } else if (!strcasecmp(v->name, "autodomain")) { 17890 auto_sip_domains = ast_true(v->value); 17891 } else if (!strcasecmp(v->name, "domain")) { 17892 char *domain = ast_strdupa(v->value); 17893 char *context = strchr(domain, ','); 17894 17895 if (context) 17896 *context++ = '\0'; 17897 17898 if (option_debug && ast_strlen_zero(context)) 17899 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 17900 if (ast_strlen_zero(domain)) 17901 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 17902 else 17903 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 17904 } else if (!strcasecmp(v->name, "register")) { 17905 if (sip_register(v->value, v->lineno) == 0) 17906 registry_count++; 17907 } else if (!strcasecmp(v->name, "tos")) { 17908 if (!ast_str2tos(v->value, &temp_tos)) { 17909 global_tos_sip = temp_tos; 17910 global_tos_audio = temp_tos; 17911 global_tos_video = temp_tos; 17912 ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno); 17913 } else 17914 ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno); 17915 } else if (!strcasecmp(v->name, "tos_sip")) { 17916 if (ast_str2tos(v->value, &global_tos_sip)) 17917 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); 17918 } else if (!strcasecmp(v->name, "tos_audio")) { 17919 if (ast_str2tos(v->value, &global_tos_audio)) 17920 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); 17921 } else if (!strcasecmp(v->name, "tos_video")) { 17922 if (ast_str2tos(v->value, &global_tos_video)) 17923 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); 17924 } else if (!strcasecmp(v->name, "bindport")) { 17925 if (sscanf(v->value, "%d", &ourport) == 1) { 17926 bindaddr.sin_port = htons(ourport); 17927 } else { 17928 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 17929 } 17930 } else if (!strcasecmp(v->name, "qualify")) { 17931 if (!strcasecmp(v->value, "no")) { 17932 default_qualify = 0; 17933 } else if (!strcasecmp(v->value, "yes")) { 17934 default_qualify = DEFAULT_MAXMS; 17935 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 17936 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 17937 default_qualify = 0; 17938 } 17939 } else if (!strcasecmp(v->name, "callevents")) { 17940 global_callevents = ast_true(v->value); 17941 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 17942 default_maxcallbitrate = atoi(v->value); 17943 if (default_maxcallbitrate < 0) 17944 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 17945 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 17946 global_matchexterniplocally = ast_true(v->value); 17947 } 17948 } 17949 17950 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 17951 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 17952 allow_external_domains = 1; 17953 } 17954 17955 /* Build list of authentication to various SIP realms, i.e. service providers */ 17956 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 17957 /* Format for authentication is auth = username:password@realm */ 17958 if (!strcasecmp(v->name, "auth")) 17959 authl = add_realm_authentication(authl, v->value, v->lineno); 17960 } 17961 17962 ucfg = ast_config_load("users.conf"); 17963 if (ucfg) { 17964 struct ast_variable *gen; 17965 int genhassip, genregistersip; 17966 const char *hassip, *registersip; 17967 17968 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 17969 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 17970 gen = ast_variable_browse(ucfg, "general"); 17971 cat = ast_category_browse(ucfg, NULL); 17972 while (cat) { 17973 if (strcasecmp(cat, "general")) { 17974 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 17975 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 17976 if (ast_true(hassip) || (!hassip && genhassip)) { 17977 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 17978 if (user) { 17979 ASTOBJ_CONTAINER_LINK(&userl,user); 17980 ASTOBJ_UNREF(user, sip_destroy_user); 17981 user_count++; 17982 } 17983 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 17984 if (peer) { 17985 ast_device_state_changed("SIP/%s", peer->name); 17986 ASTOBJ_CONTAINER_LINK(&peerl,peer); 17987 ASTOBJ_UNREF(peer, sip_destroy_peer); 17988 peer_count++; 17989 } 17990 } 17991 if (ast_true(registersip) || (!registersip && genregistersip)) { 17992 char tmp[256]; 17993 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 17994 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 17995 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 17996 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 17997 if (!host) 17998 host = ast_variable_retrieve(ucfg, "general", "host"); 17999 if (!username) 18000 username = ast_variable_retrieve(ucfg, "general", "username"); 18001 if (!secret) 18002 secret = ast_variable_retrieve(ucfg, "general", "secret"); 18003 if (!contact) 18004 contact = "s"; 18005 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 18006 if (!ast_strlen_zero(secret)) 18007 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 18008 else 18009 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 18010 if (sip_register(tmp, 0) == 0) 18011 registry_count++; 18012 } 18013 } 18014 } 18015 cat = ast_category_browse(ucfg, cat); 18016 } 18017 ast_config_destroy(ucfg); 18018 } 18019 18020 18021 /* Load peers, users and friends */ 18022 cat = NULL; 18023 while ( (cat = ast_category_browse(cfg, cat)) ) { 18024 const char *utype; 18025 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 18026 continue; 18027 utype = ast_variable_retrieve(cfg, cat, "type"); 18028 if (!utype) { 18029 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 18030 continue; 18031 } else { 18032 int is_user = 0, is_peer = 0; 18033 if (!strcasecmp(utype, "user")) 18034 is_user = 1; 18035 else if (!strcasecmp(utype, "friend")) 18036 is_user = is_peer = 1; 18037 else if (!strcasecmp(utype, "peer")) 18038 is_peer = 1; 18039 else { 18040 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 18041 continue; 18042 } 18043 if (is_user) { 18044 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 18045 if (user) { 18046 ASTOBJ_CONTAINER_LINK(&userl,user); 18047 ASTOBJ_UNREF(user, sip_destroy_user); 18048 user_count++; 18049 } 18050 } 18051 if (is_peer) { 18052 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 18053 if (peer) { 18054 ASTOBJ_CONTAINER_LINK(&peerl,peer); 18055 ASTOBJ_UNREF(peer, sip_destroy_peer); 18056 peer_count++; 18057 } 18058 } 18059 } 18060 } 18061 if (ast_find_ourip(&__ourip, bindaddr)) { 18062 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 18063 ast_config_destroy(cfg); 18064 return 0; 18065 } 18066 if (!ntohs(bindaddr.sin_port)) 18067 bindaddr.sin_port = ntohs(STANDARD_SIP_PORT); 18068 bindaddr.sin_family = AF_INET; 18069 ast_mutex_lock(&netlock); 18070 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 18071 close(sipsock); 18072 sipsock = -1; 18073 } 18074 if (sipsock < 0) { 18075 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 18076 if (sipsock < 0) { 18077 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 18078 ast_config_destroy(cfg); 18079 return -1; 18080 } else { 18081 /* Allow SIP clients on the same host to access us: */ 18082 const int reuseFlag = 1; 18083 18084 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 18085 (const char*)&reuseFlag, 18086 sizeof reuseFlag); 18087 18088 ast_enable_packet_fragmentation(sipsock); 18089 18090 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 18091 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 18092 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 18093 strerror(errno)); 18094 close(sipsock); 18095 sipsock = -1; 18096 } else { 18097 if (option_verbose > 1) { 18098 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 18099 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 18100 ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip)); 18101 } 18102 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 18103 ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip)); 18104 } 18105 } 18106 } 18107 ast_mutex_unlock(&netlock); 18108 18109 /* Add default domains - host name, IP address and IP:port */ 18110 /* Only do this if user added any sip domain with "localdomains" */ 18111 /* In order to *not* break backwards compatibility */ 18112 /* Some phones address us at IP only, some with additional port number */ 18113 if (auto_sip_domains) { 18114 char temp[MAXHOSTNAMELEN]; 18115 18116 /* First our default IP address */ 18117 if (bindaddr.sin_addr.s_addr) 18118 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 18119 else 18120 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 18121 18122 /* Our extern IP address, if configured */ 18123 if (externip.sin_addr.s_addr) 18124 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 18125 18126 /* Extern host name (NAT traversal support) */ 18127 if (!ast_strlen_zero(externhost)) 18128 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 18129 18130 /* Our host name */ 18131 if (!gethostname(temp, sizeof(temp))) 18132 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 18133 } 18134 18135 /* Release configuration from memory */ 18136 ast_config_destroy(cfg); 18137 18138 /* Load the list of manual NOTIFY types to support */ 18139 if (notify_types) 18140 ast_config_destroy(notify_types); 18141 notify_types = ast_config_load(notify_config); 18142 18143 /* Done, tell the manager */ 18144 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); 18145 18146 return 0; 18147 }
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 11720 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().
11721 { 11722 char tmp[512]; 11723 char *c; 11724 char oldnonce[256]; 11725 11726 /* table of recognised keywords, and places where they should be copied */ 11727 const struct x { 11728 const char *key; 11729 int field_index; 11730 } *i, keys[] = { 11731 { "realm=", ast_string_field_index(p, realm) }, 11732 { "nonce=", ast_string_field_index(p, nonce) }, 11733 { "opaque=", ast_string_field_index(p, opaque) }, 11734 { "qop=", ast_string_field_index(p, qop) }, 11735 { "domain=", ast_string_field_index(p, domain) }, 11736 { NULL, 0 }, 11737 }; 11738 11739 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 11740 if (ast_strlen_zero(tmp)) 11741 return -1; 11742 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 11743 ast_log(LOG_WARNING, "missing Digest.\n"); 11744 return -1; 11745 } 11746 c = tmp + strlen("Digest "); 11747 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 11748 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 11749 for (i = keys; i->key != NULL; i++) { 11750 char *src, *separator; 11751 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 11752 continue; 11753 /* Found. Skip keyword, take text in quotes or up to the separator. */ 11754 c += strlen(i->key); 11755 if (*c == '"') { 11756 src = ++c; 11757 separator = "\""; 11758 } else { 11759 src = c; 11760 separator = ","; 11761 } 11762 strsep(&c, separator); /* clear separator and move ptr */ 11763 ast_string_field_index_set(p, i->field_index, src); 11764 break; 11765 } 11766 if (i->key == NULL) /* not found, try ',' */ 11767 strsep(&c, ","); 11768 } 11769 /* Reset nonce count */ 11770 if (strcmp(p->nonce, oldnonce)) 11771 p->noncecount = 0; 11772 11773 /* Save auth data for following registrations */ 11774 if (p->registry) { 11775 struct sip_registry *r = p->registry; 11776 11777 if (strcmp(r->nonce, p->nonce)) { 11778 ast_string_field_set(r, realm, p->realm); 11779 ast_string_field_set(r, nonce, p->nonce); 11780 ast_string_field_set(r, domain, p->domain); 11781 ast_string_field_set(r, opaque, p->opaque); 11782 ast_string_field_set(r, qop, p->qop); 11783 r->noncecount = 0; 11784 } 11785 } 11786 return build_reply_digest(p, sipmethod, digest, digest_len); 11787 }
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 6062 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.
06063 { 06064 struct sip_request *orig = &p->initreq; 06065 char stripped[80]; 06066 char tmp[80]; 06067 char newto[256]; 06068 const char *c; 06069 const char *ot, *of; 06070 int is_strict = FALSE; /*!< Strict routing flag */ 06071 06072 memset(req, 0, sizeof(struct sip_request)); 06073 06074 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 06075 06076 if (!seqno) { 06077 p->ocseq++; 06078 seqno = p->ocseq; 06079 } 06080 06081 if (sipmethod == SIP_CANCEL) { 06082 p->branch = p->invite_branch; 06083 build_via(p); 06084 } else if (newbranch) { 06085 p->branch ^= ast_random(); 06086 build_via(p); 06087 } 06088 06089 /* Check for strict or loose router */ 06090 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) { 06091 is_strict = TRUE; 06092 if (sipdebug) 06093 ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid); 06094 } 06095 06096 if (sipmethod == SIP_CANCEL) 06097 c = p->initreq.rlPart2; /* Use original URI */ 06098 else if (sipmethod == SIP_ACK) { 06099 /* Use URI from Contact: in 200 OK (if INVITE) 06100 (we only have the contacturi on INVITEs) */ 06101 if (!ast_strlen_zero(p->okcontacturi)) 06102 c = is_strict ? p->route->hop : p->okcontacturi; 06103 else 06104 c = p->initreq.rlPart2; 06105 } else if (!ast_strlen_zero(p->okcontacturi)) 06106 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 06107 else if (!ast_strlen_zero(p->uri)) 06108 c = p->uri; 06109 else { 06110 char *n; 06111 /* We have no URI, use To: or From: header as URI (depending on direction) */ 06112 ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"), 06113 sizeof(stripped)); 06114 n = get_in_brackets(stripped); 06115 c = strsep(&n, ";"); /* trim ; and beyond */ 06116 } 06117 init_req(req, sipmethod, c); 06118 06119 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 06120 06121 add_header(req, "Via", p->via); 06122 if (p->route) { 06123 set_destination(p, p->route->hop); 06124 add_route(req, is_strict ? p->route->next : p->route); 06125 } 06126 06127 ot = get_header(orig, "To"); 06128 of = get_header(orig, "From"); 06129 06130 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 06131 as our original request, including tag (or presumably lack thereof) */ 06132 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 06133 /* Add the proper tag if we don't have it already. If they have specified 06134 their tag, use it. Otherwise, use our own tag */ 06135 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 06136 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06137 else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06138 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06139 else 06140 snprintf(newto, sizeof(newto), "%s", ot); 06141 ot = newto; 06142 } 06143 06144 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06145 add_header(req, "From", of); 06146 add_header(req, "To", ot); 06147 } else { 06148 add_header(req, "From", ot); 06149 add_header(req, "To", of); 06150 } 06151 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 06152 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 06153 add_header(req, "Contact", p->our_contact); 06154 06155 copy_header(req, orig, "Call-ID"); 06156 add_header(req, "CSeq", tmp); 06157 06158 if (!ast_strlen_zero(global_useragent)) 06159 add_header(req, "User-Agent", global_useragent); 06160 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 06161 06162 if (!ast_strlen_zero(p->rpid)) 06163 add_header(req, "Remote-Party-ID", p->rpid); 06164 06165 return 0; 06166 }
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 6014 of file chan_sip.c.
References add_header(), ALLOWED_METHODS, ast_copy_string(), ast_strlen_zero(), ast_test_flag, copy_all_header(), copy_header(), copy_via_headers(), sip_pvt::expiry, sip_pvt::flags, get_header(), init_resp(), sip_pvt::method, sip_pvt::our_contact, SIP_OUTGOING, SIP_REGISTER, SIP_SUBSCRIBE, SIPBUFSIZE, SUPPORTED_EXTENSIONS, sip_pvt::tag, and sip_pvt::theirtag.
06015 { 06016 char newto[256]; 06017 const char *ot; 06018 06019 init_resp(resp, msg); 06020 copy_via_headers(p, resp, req, "Via"); 06021 if (msg[0] == '1' || msg[0] == '2') 06022 copy_all_header(resp, req, "Record-Route"); 06023 copy_header(resp, req, "From"); 06024 ot = get_header(req, "To"); 06025 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 06026 /* Add the proper tag if we don't have it already. If they have specified 06027 their tag, use it. Otherwise, use our own tag */ 06028 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06029 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 06030 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 06031 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 06032 else 06033 ast_copy_string(newto, ot, sizeof(newto)); 06034 ot = newto; 06035 } 06036 add_header(resp, "To", ot); 06037 copy_header(resp, req, "Call-ID"); 06038 copy_header(resp, req, "CSeq"); 06039 if (!ast_strlen_zero(global_useragent)) 06040 add_header(resp, "User-Agent", global_useragent); 06041 add_header(resp, "Allow", ALLOWED_METHODS); 06042 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 06043 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 06044 /* For registration responses, we also need expiry and 06045 contact info */ 06046 char tmp[256]; 06047 06048 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 06049 add_header(resp, "Expires", tmp); 06050 if (p->expiry) { /* Only add contact if we have an expiry time */ 06051 char contact[SIPBUFSIZE]; 06052 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 06053 add_header(resp, "Contact", contact); /* Not when we unregister */ 06054 } 06055 } else if (msg[0] != '4' && !ast_strlen_zero(p->our_contact)) { 06056 add_header(resp, "Contact", p->our_contact); 06057 } 06058 return 0; 06059 }
static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 16431 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.
16432 { 16433 /* If we're supposed to be stopped -- stay stopped */ 16434 if (monitor_thread == AST_PTHREADT_STOP) 16435 return 0; 16436 ast_mutex_lock(&monlock); 16437 if (monitor_thread == pthread_self()) { 16438 ast_mutex_unlock(&monlock); 16439 ast_log(LOG_WARNING, "Cannot kill myself\n"); 16440 return -1; 16441 } 16442 if (monitor_thread != AST_PTHREADT_NULL) { 16443 /* Wake up the thread */ 16444 pthread_kill(monitor_thread, SIGURG); 16445 } else { 16446 /* Start a new monitor */ 16447 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 16448 ast_mutex_unlock(&monlock); 16449 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 16450 return -1; 16451 } 16452 } 16453 ast_mutex_unlock(&monlock); 16454 return 0; 16455 }
static int retrans_pkt | ( | const void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 1913 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.
01914 { 01915 struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL; 01916 int reschedule = DEFAULT_RETRANS; 01917 int xmitres = 0; 01918 01919 /* Lock channel PVT */ 01920 ast_mutex_lock(&pkt->owner->lock); 01921 01922 if (pkt->retrans < MAX_RETRANS) { 01923 pkt->retrans++; 01924 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 01925 if (sipdebug && option_debug > 3) 01926 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); 01927 } else { 01928 int siptimer_a; 01929 01930 if (sipdebug && option_debug > 3) 01931 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 01932 if (!pkt->timer_a) 01933 pkt->timer_a = 2 ; 01934 else 01935 pkt->timer_a = 2 * pkt->timer_a; 01936 01937 /* For non-invites, a maximum of 4 secs */ 01938 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 01939 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 01940 siptimer_a = 4000; 01941 01942 /* Reschedule re-transmit */ 01943 reschedule = siptimer_a; 01944 if (option_debug > 3) 01945 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); 01946 } 01947 01948 if (sip_debug_test_pvt(pkt->owner)) { 01949 const struct sockaddr_in *dst = sip_real_dst(pkt->owner); 01950 ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n", 01951 pkt->retrans, sip_nat_mode(pkt->owner), 01952 ast_inet_ntoa(dst->sin_addr), 01953 ntohs(dst->sin_port), pkt->data); 01954 } 01955 01956 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data); 01957 xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 01958 ast_mutex_unlock(&pkt->owner->lock); 01959 if (xmitres == XMIT_ERROR) 01960 ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid); 01961 else 01962 return reschedule; 01963 } 01964 /* Too many retries */ 01965 if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) { 01966 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 01967 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); 01968 } else if ((pkt->method == SIP_OPTIONS) && sipdebug) { 01969 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) -- See doc/sip-retransmit.txt.\n", pkt->owner->callid); 01970 } 01971 if (xmitres == XMIT_ERROR) { 01972 ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission of transaction in call id %s \n", pkt->owner->callid); 01973 append_history(pkt->owner, "XmitErr", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01974 } else 01975 append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01976 01977 pkt->retransid = -1; 01978 01979 if (ast_test_flag(pkt, FLAG_FATAL)) { 01980 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 01981 DEADLOCK_AVOIDANCE(&pkt->owner->lock); /* SIP_PVT, not channel */ 01982 } 01983 01984 if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 01985 pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE; 01986 01987 if (pkt->owner->owner) { 01988 sip_alreadygone(pkt->owner); 01989 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); 01990 ast_queue_hangup(pkt->owner->owner); 01991 ast_channel_unlock(pkt->owner->owner); 01992 } else { 01993 /* If no channel owner, destroy now */ 01994 01995 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 01996 if (pkt->method != SIP_OPTIONS) { 01997 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 01998 sip_alreadygone(pkt->owner); 01999 if (option_debug) 02000 append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately"); 02001 } 02002 } 02003 } 02004 02005 if (pkt->method == SIP_BYE) { 02006 /* We're not getting answers on SIP BYE's. Tear down the call anyway. */ 02007 if (pkt->owner->owner) 02008 ast_channel_unlock(pkt->owner->owner); 02009 append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway."); 02010 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 02011 } 02012 02013 /* In any case, go ahead and remove the packet */ 02014 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 02015 if (cur == pkt) 02016 break; 02017 } 02018 if (cur) { 02019 if (prev) 02020 prev->next = cur->next; 02021 else 02022 pkt->owner->packets = cur->next; 02023 ast_mutex_unlock(&pkt->owner->lock); 02024 free(cur); 02025 pkt = NULL; 02026 } else 02027 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 02028 if (pkt) 02029 ast_mutex_unlock(&pkt->owner->lock); 02030 return 0; 02031 }
static int scheduler_process_request_queue | ( | const void * | data | ) | [static] |
Definition at line 15996 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().
15997 { 15998 struct sip_pvt *p = (struct sip_pvt *) data; 15999 int recount = 0; 16000 int nounlock = 0; 16001 int lockretry; 16002 16003 for (lockretry = 10; lockretry > 0; lockretry--) { 16004 ast_mutex_lock(&p->lock); 16005 16006 /* lock the owner if it has one -- we may need it */ 16007 /* because this is deadlock-prone, we need to try and unlock if failed */ 16008 if (!p->owner || !ast_channel_trylock(p->owner)) { 16009 break; /* locking succeeded */ 16010 } 16011 16012 if (lockretry != 1) { 16013 ast_mutex_unlock(&p->lock); 16014 /* Sleep for a very short amount of time */ 16015 usleep(1); 16016 } 16017 } 16018 16019 if (!lockretry) { 16020 int retry = !AST_LIST_EMPTY(&p->request_queue); 16021 16022 /* we couldn't get the owner lock, which is needed to process 16023 the queued requests, so return a non-zero value, which will 16024 cause the scheduler to run this request again later if there 16025 still requests to be processed 16026 */ 16027 ast_mutex_unlock(&p->lock); 16028 return retry; 16029 }; 16030 16031 process_request_queue(p, &recount, &nounlock); 16032 p->request_queue_sched_id = -1; 16033 16034 if (p->owner && !nounlock) { 16035 ast_channel_unlock(p->owner); 16036 } 16037 ast_mutex_unlock(&p->lock); 16038 16039 if (recount) { 16040 ast_update_use_count(); 16041 } 16042 16043 return 0; 16044 }
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 2311 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.
02312 { 02313 int res; 02314 02315 add_blank(req); 02316 if (sip_debug_test_pvt(p)) { 02317 if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)) 02318 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); 02319 else 02320 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); 02321 } 02322 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02323 struct sip_request tmp; 02324 parse_copy(&tmp, req); 02325 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 02326 } 02327 res = (reliable) ? 02328 __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02329 __sip_xmit(p, req->data, req->len); 02330 return res; 02331 }
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 2283 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.
02284 { 02285 int res; 02286 02287 add_blank(req); 02288 if (sip_debug_test_pvt(p)) { 02289 const struct sockaddr_in *dst = sip_real_dst(p); 02290 02291 ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n", 02292 reliable ? "Reliably " : "", sip_nat_mode(p), 02293 ast_inet_ntoa(dst->sin_addr), 02294 ntohs(dst->sin_port), req->data); 02295 } 02296 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02297 struct sip_request tmp; 02298 parse_copy(&tmp, req); 02299 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 02300 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text); 02301 } 02302 res = (reliable) ? 02303 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02304 __sip_xmit(p, req->data, req->len); 02305 if (res > 0) 02306 return 0; 02307 return res; 02308 }
static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 8256 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().
08257 { 08258 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 08259 /* NAT: Don't trust the contact field. Just use what they came to us 08260 with. */ 08261 pvt->sa = pvt->recv; 08262 return 0; 08263 } 08264 08265 return __set_address_from_contact(pvt->fullcontact, &pvt->sa); 08266 }
static void set_destination | ( | struct sip_pvt * | p, | |
char * | uri | |||
) | [static] |
Set destination from SIP URI.
Definition at line 5923 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().
05924 { 05925 char *h, *maddr, hostname[256]; 05926 int port, hn; 05927 struct hostent *hp; 05928 struct ast_hostent ahp; 05929 int debug=sip_debug_test_pvt(p); 05930 05931 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 05932 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 05933 05934 if (debug) 05935 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 05936 05937 /* Find and parse hostname */ 05938 h = strchr(uri, '@'); 05939 if (h) 05940 ++h; 05941 else { 05942 h = uri; 05943 if (strncasecmp(h, "sip:", 4) == 0) 05944 h += 4; 05945 else if (strncasecmp(h, "sips:", 5) == 0) 05946 h += 5; 05947 } 05948 hn = strcspn(h, ":;>") + 1; 05949 if (hn > sizeof(hostname)) 05950 hn = sizeof(hostname); 05951 ast_copy_string(hostname, h, hn); 05952 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 05953 h += hn - 1; 05954 05955 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 05956 if (*h == ':') { 05957 /* Parse port */ 05958 ++h; 05959 port = strtol(h, &h, 10); 05960 } 05961 else 05962 port = STANDARD_SIP_PORT; 05963 05964 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 05965 maddr = strstr(h, "maddr="); 05966 if (maddr) { 05967 maddr += 6; 05968 hn = strspn(maddr, "0123456789.") + 1; 05969 if (hn > sizeof(hostname)) 05970 hn = sizeof(hostname); 05971 ast_copy_string(hostname, maddr, hn); 05972 } 05973 05974 hp = ast_gethostbyname(hostname, &ahp); 05975 if (hp == NULL) { 05976 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 05977 return; 05978 } 05979 p->sa.sin_family = AF_INET; 05980 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 05981 p->sa.sin_port = htons(port); 05982 if (debug) 05983 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 05984 }
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 16765 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().
16766 { 16767 static int dep_insecure_very = 0; 16768 static int dep_insecure_yes = 0; 16769 16770 if (ast_strlen_zero(value)) 16771 return; 16772 16773 if (!strcasecmp(value, "very")) { 16774 ast_set_flag(flags, SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 16775 if(!dep_insecure_very) { 16776 if(lineno != -1) 16777 ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", lineno); 16778 else 16779 ast_log(LOG_WARNING, "insecure=very is deprecated; use insecure=port,invite instead\n"); 16780 dep_insecure_very = 1; 16781 } 16782 } 16783 else if (ast_true(value)) { 16784 ast_set_flag(flags, SIP_INSECURE_PORT); 16785 if(!dep_insecure_yes) { 16786 if(lineno != -1) 16787 ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", value, lineno); 16788 else 16789 ast_log(LOG_WARNING, "insecure=%s is deprecated; use insecure=port instead\n", value); 16790 dep_insecure_yes = 1; 16791 } 16792 } 16793 else if (!ast_false(value)) { 16794 char buf[64]; 16795 char *word, *next; 16796 ast_copy_string(buf, value, sizeof(buf)); 16797 next = buf; 16798 while ((word = strsep(&next, ","))) { 16799 if (!strcasecmp(word, "port")) 16800 ast_set_flag(flags, SIP_INSECURE_PORT); 16801 else if (!strcasecmp(word, "invite")) 16802 ast_set_flag(flags, SIP_INSECURE_INVITE); 16803 else 16804 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno); 16805 } 16806 } 16807 }
static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 17196 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().
17197 { 17198 if (peer->expire == 0) { 17199 /* Don't reset expire or port time during reload 17200 if we have an active registration 17201 */ 17202 peer->expire = -1; 17203 peer->pokeexpire = -1; 17204 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 17205 } 17206 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 17207 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 17208 strcpy(peer->context, default_context); 17209 strcpy(peer->subscribecontext, default_subscribecontext); 17210 strcpy(peer->language, default_language); 17211 strcpy(peer->mohinterpret, default_mohinterpret); 17212 strcpy(peer->mohsuggest, default_mohsuggest); 17213 peer->addr.sin_family = AF_INET; 17214 peer->defaddr.sin_family = AF_INET; 17215 peer->capability = global_capability; 17216 peer->maxcallbitrate = default_maxcallbitrate; 17217 peer->rtptimeout = global_rtptimeout; 17218 peer->rtpholdtimeout = global_rtpholdtimeout; 17219 peer->rtpkeepalive = global_rtpkeepalive; 17220 peer->allowtransfer = global_allowtransfer; 17221 peer->autoframing = global_autoframing; 17222 strcpy(peer->vmexten, default_vmexten); 17223 peer->secret[0] = '\0'; 17224 peer->md5secret[0] = '\0'; 17225 peer->cid_num[0] = '\0'; 17226 peer->cid_name[0] = '\0'; 17227 peer->fromdomain[0] = '\0'; 17228 peer->fromuser[0] = '\0'; 17229 peer->regexten[0] = '\0'; 17230 peer->mailbox[0] = '\0'; 17231 peer->callgroup = 0; 17232 peer->pickupgroup = 0; 17233 peer->maxms = default_qualify; 17234 peer->prefs = default_prefs; 17235 }
static int sip_addheader | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 18486 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().
18487 { 18488 int no = 0; 18489 int ok = FALSE; 18490 char varbuf[30]; 18491 char *inbuf = (char *) data; 18492 18493 if (ast_strlen_zero(inbuf)) { 18494 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 18495 return 0; 18496 } 18497 ast_channel_lock(chan); 18498 18499 /* Check for headers */ 18500 while (!ok && no <= 50) { 18501 no++; 18502 snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no); 18503 18504 /* Compare without the leading underscores */ 18505 if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL) ) 18506 ok = TRUE; 18507 } 18508 if (ok) { 18509 pbx_builtin_setvar_helper (chan, varbuf, inbuf); 18510 if (sipdebug) 18511 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf); 18512 } else { 18513 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 18514 } 18515 ast_channel_unlock(chan); 18516 return 0; 18517 }
static int sip_addrcmp | ( | char * | name, | |
struct sockaddr_in * | sin | |||
) | [static] |
Support routine for find_peer.
Definition at line 2676 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, inaddrcmp(), and SIP_INSECURE_PORT.
Referenced by find_peer().
02677 { 02678 /* We know name is the first field, so we can cast */ 02679 struct sip_peer *p = (struct sip_peer *) name; 02680 return !(!inaddrcmp(&p->addr, sin) || 02681 (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) && 02682 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 02683 }
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 4527 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().
04529 { 04530 struct sip_pvt *p; 04531 04532 if (!(p = ast_calloc(1, sizeof(*p)))) 04533 return NULL; 04534 04535 if (ast_string_field_init(p, 512)) { 04536 free(p); 04537 return NULL; 04538 } 04539 04540 ast_mutex_init(&p->lock); 04541 04542 p->method = intended_method; 04543 p->initid = -1; 04544 p->waitid = -1; 04545 p->autokillid = -1; 04546 p->request_queue_sched_id = -1; 04547 p->subscribed = NONE; 04548 p->stateid = -1; 04549 p->prefs = default_prefs; /* Set default codecs for this call */ 04550 04551 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 04552 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 04553 04554 if (sin) { 04555 p->sa = *sin; 04556 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 04557 p->ourip = __ourip; 04558 } else 04559 p->ourip = __ourip; 04560 04561 /* Copy global flags to this PVT at setup. */ 04562 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 04563 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 04564 04565 ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY); 04566 04567 p->branch = ast_random(); 04568 make_our_tag(p->tag, sizeof(p->tag)); 04569 p->ocseq = INITIAL_CSEQ; 04570 04571 if (sip_methods[intended_method].need_rtp) { 04572 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04573 /* If the global videosupport flag is on, we always create a RTP interface for video */ 04574 if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 04575 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04576 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) 04577 p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 04578 if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) { 04579 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", 04580 ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno)); 04581 ast_mutex_destroy(&p->lock); 04582 if (p->chanvars) { 04583 ast_variables_destroy(p->chanvars); 04584 p->chanvars = NULL; 04585 } 04586 free(p); 04587 return NULL; 04588 } 04589 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04590 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04591 ast_rtp_settos(p->rtp, global_tos_audio); 04592 ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); 04593 ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); 04594 ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); 04595 if (p->vrtp) { 04596 ast_rtp_settos(p->vrtp, global_tos_video); 04597 ast_rtp_setdtmf(p->vrtp, 0); 04598 ast_rtp_setdtmfcompensate(p->vrtp, 0); 04599 ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); 04600 ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout); 04601 ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); 04602 } 04603 if (p->udptl) 04604 ast_udptl_settos(p->udptl, global_tos_audio); 04605 p->maxcallbitrate = default_maxcallbitrate; 04606 p->autoframing = global_autoframing; 04607 ast_rtp_codec_setpref(p->rtp, &p->prefs); 04608 } 04609 04610 if (useglobal_nat && sin) { 04611 /* Setup NAT structure according to global settings if we have an address */ 04612 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 04613 p->recv = *sin; 04614 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04615 } 04616 04617 if (p->method != SIP_REGISTER) 04618 ast_string_field_set(p, fromdomain, default_fromdomain); 04619 build_via(p); 04620 if (!callid) 04621 build_callid_pvt(p); 04622 else 04623 ast_string_field_set(p, callid, callid); 04624 /* Assign default music on hold class */ 04625 ast_string_field_set(p, mohinterpret, default_mohinterpret); 04626 ast_string_field_set(p, mohsuggest, default_mohsuggest); 04627 p->capability = global_capability; 04628 p->allowtransfer = global_allowtransfer; 04629 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 04630 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 04631 p->noncodeccapability |= AST_RTP_DTMF; 04632 if (p->udptl) { 04633 p->t38.capability = global_t38_capability; 04634 if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY) 04635 p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 04636 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC) 04637 p->t38.capability |= T38FAX_UDP_EC_FEC; 04638 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE) 04639 p->t38.capability |= T38FAX_UDP_EC_NONE; 04640 p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 04641 p->t38.jointcapability = p->t38.capability; 04642 } 04643 ast_string_field_set(p, context, default_context); 04644 04645 AST_LIST_HEAD_INIT_NOLOCK(&p->request_queue); 04646 04647 /* Add to active dialog list */ 04648 ast_mutex_lock(&iflock); 04649 p->next = iflist; 04650 iflist = p; 04651 ast_mutex_unlock(&iflock); 04652 if (option_debug) 04653 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"); 04654 return p; 04655 }
static void sip_alreadygone | ( | struct sip_pvt * | dialog | ) | [static] |
Definition at line 1671 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().
01672 { 01673 if (option_debug > 2) 01674 ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 01675 ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE); 01676 }
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 3715 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.
03716 { 03717 int res = 0; 03718 struct sip_pvt *p = ast->tech_pvt; 03719 03720 ast_mutex_lock(&p->lock); 03721 if (ast->_state != AST_STATE_UP) { 03722 try_suggested_sip_codec(p); 03723 03724 ast_setstate(ast, AST_STATE_UP); 03725 if (option_debug) 03726 ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name); 03727 if (p->t38.state == T38_PEER_DIRECT) { 03728 p->t38.state = T38_ENABLED; 03729 if (option_debug > 1) 03730 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 03731 res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03732 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 03733 } else { 03734 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03735 ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED); 03736 } 03737 } 03738 ast_mutex_unlock(&p->lock); 03739 return res; 03740 }
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 2985 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.
02986 { 02987 int res, xmitres = 0; 02988 struct sip_pvt *p; 02989 struct varshead *headp; 02990 struct ast_var_t *current; 02991 const char *referer = NULL; /* SIP refererer */ 02992 02993 p = ast->tech_pvt; 02994 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 02995 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 02996 return -1; 02997 } 02998 02999 /* Check whether there is vxml_url, distinctive ring variables */ 03000 headp=&ast->varshead; 03001 AST_LIST_TRAVERSE(headp,current,entries) { 03002 /* Check whether there is a VXML_URL variable */ 03003 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 03004 p->options->vxml_url = ast_var_value(current); 03005 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 03006 p->options->uri_options = ast_var_value(current); 03007 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 03008 /* Check whether there is a ALERT_INFO variable */ 03009 p->options->distinctive_ring = ast_var_value(current); 03010 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 03011 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 03012 p->options->addsipheaders = 1; 03013 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 03014 /* This is a transfered call */ 03015 p->options->transfer = 1; 03016 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 03017 /* This is the referer */ 03018 referer = ast_var_value(current); 03019 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 03020 /* We're replacing a call. */ 03021 p->options->replaces = ast_var_value(current); 03022 } else if (!strcasecmp(ast_var_name(current), "T38CALL")) { 03023 p->t38.state = T38_LOCAL_DIRECT; 03024 if (option_debug) 03025 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 03026 } 03027 03028 } 03029 03030 res = 0; 03031 ast_set_flag(&p->flags[0], SIP_OUTGOING); 03032 03033 if (p->options->transfer) { 03034 char buf[SIPBUFSIZE/2]; 03035 03036 if (referer) { 03037 if (sipdebug && option_debug > 2) 03038 ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer); 03039 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 03040 } else 03041 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 03042 ast_string_field_set(p, cid_name, buf); 03043 } 03044 if (option_debug) 03045 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 03046 03047 res = update_call_counter(p, INC_CALL_RINGING); 03048 if ( res != -1 ) { 03049 p->callingpres = ast->cid.cid_pres; 03050 p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec); 03051 p->jointnoncodeccapability = p->noncodeccapability; 03052 03053 /* If there are no audio formats left to offer, punt */ 03054 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 03055 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 03056 res = -1; 03057 } else { 03058 p->t38.jointcapability = p->t38.capability; 03059 if (option_debug > 1) 03060 ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability); 03061 xmitres = transmit_invite(p, SIP_INVITE, 1, 2); 03062 if (xmitres == XMIT_ERROR) 03063 return -1; /* Transmission error */ 03064 03065 p->invitestate = INV_CALLING; 03066 03067 /* Initialize auto-congest time */ 03068 AST_SCHED_DEL(sched, p->initid); 03069 p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p); 03070 } 03071 } else { 03072 ast->hangupcause = AST_CAUSE_USER_BUSY; 03073 } 03074 return res; 03075 }
static int sip_cancel_destroy | ( | struct sip_pvt * | p | ) | [static] |
Cancel destruction of SIP dialog.
Definition at line 2153 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().
02154 { 02155 int res = 0; 02156 if (p->autokillid > -1) { 02157 if (!(res = ast_sched_del(sched, p->autokillid))) { 02158 append_history(p, "CancelDestroy", ""); 02159 p->autokillid = -1; 02160 } 02161 } 02162 return res; 02163 }
static int sip_debug_test_addr | ( | const struct sockaddr_in * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 1753 of file chan_sip.c.
References sipdebug.
Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().
01754 { 01755 if (!sipdebug) 01756 return 0; 01757 if (debugaddr.sin_addr.s_addr) { 01758 if (((ntohs(debugaddr.sin_port) != 0) 01759 && (debugaddr.sin_port != addr->sin_port)) 01760 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01761 return 0; 01762 } 01763 return 1; 01764 }
static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 1779 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().
01780 { 01781 if (!sipdebug) 01782 return 0; 01783 return sip_debug_test_addr(sip_real_dst(p)); 01784 }
static void sip_destroy | ( | struct sip_pvt * | p | ) | [static] |
Destroy SIP call structure.
Definition at line 3357 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().
03358 { 03359 ast_mutex_lock(&iflock); 03360 if (option_debug > 2) 03361 ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid); 03362 __sip_destroy(p, 1); 03363 ast_mutex_unlock(&iflock); 03364 }
static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 2486 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().
02487 { 02488 if (option_debug > 2) 02489 ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name); 02490 02491 /* Delete it, it needs to disappear */ 02492 if (peer->call) 02493 sip_destroy(peer->call); 02494 02495 if (peer->mwipvt) /* We have an active subscription, delete it */ 02496 sip_destroy(peer->mwipvt); 02497 02498 if (peer->chanvars) { 02499 ast_variables_destroy(peer->chanvars); 02500 peer->chanvars = NULL; 02501 } 02502 02503 register_peer_exten(peer, FALSE); 02504 ast_free_ha(peer->ha); 02505 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT)) 02506 apeerobjs--; 02507 else if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) 02508 rpeerobjs--; 02509 else 02510 speerobjs--; 02511 clear_realm_authentication(peer->auth); 02512 peer->auth = NULL; 02513 free(peer); 02514 }
static void sip_destroy_user | ( | struct sip_user * | user | ) | [static] |
Remove user object from in-memory storage.
Definition at line 2704 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().
02705 { 02706 if (option_debug > 2) 02707 ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name); 02708 ast_free_ha(user->ha); 02709 if (user->chanvars) { 02710 ast_variables_destroy(user->chanvars); 02711 user->chanvars = NULL; 02712 } 02713 if (ast_test_flag(&user->flags[0], SIP_REALTIME)) 02714 ruserobjs--; 02715 else 02716 suserobjs--; 02717 free(user); 02718 }
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 16600 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().
16601 { 16602 char *host; 16603 char *tmp; 16604 16605 struct hostent *hp; 16606 struct ast_hostent ahp; 16607 struct sip_peer *p; 16608 16609 int res = AST_DEVICE_INVALID; 16610 16611 /* make sure data is not null. Maybe unnecessary, but better be safe */ 16612 host = ast_strdupa(data ? data : ""); 16613 if ((tmp = strchr(host, '@'))) 16614 host = tmp + 1; 16615 16616 if (option_debug > 2) 16617 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 16618 16619 /* If find_peer asks for a realtime peer, then this breaks rtautoclear. This 16620 * is because when a peer tries to autoexpire, the last thing it does is to 16621 * queue up an event telling the system that the devicestate has changed 16622 * (presumably to unavailable). If we ask for a realtime peer here, this would 16623 * load it BACK into memory, thus defeating the point of trying to trying to 16624 * clear dead hosts out of memory. 16625 */ 16626 if ((p = find_peer(host, NULL, 0, 1))) { 16627 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 16628 /* we have an address for the peer */ 16629 16630 /* Check status in this order 16631 - Hold 16632 - Ringing 16633 - Busy (enforced only by call limit) 16634 - Inuse (we have a call) 16635 - Unreachable (qualify) 16636 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 16637 for registered devices */ 16638 16639 if (p->onHold) 16640 /* First check for hold or ring states */ 16641 res = AST_DEVICE_ONHOLD; 16642 else if (p->inRinging) { 16643 if (p->inRinging == p->inUse) 16644 res = AST_DEVICE_RINGING; 16645 else 16646 res = AST_DEVICE_RINGINUSE; 16647 } else if (p->call_limit && (p->inUse == p->call_limit)) 16648 /* check call limit */ 16649 res = AST_DEVICE_BUSY; 16650 else if (p->call_limit && p->inUse) 16651 /* Not busy, but we do have a call */ 16652 res = AST_DEVICE_INUSE; 16653 else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 16654 /* We don't have a call. Are we reachable at all? Requires qualify= */ 16655 res = AST_DEVICE_UNAVAILABLE; 16656 else /* Default reply if we're registered and have no other data */ 16657 res = AST_DEVICE_NOT_INUSE; 16658 } else { 16659 /* there is no address, it's unavailable */ 16660 res = AST_DEVICE_UNAVAILABLE; 16661 } 16662 ASTOBJ_UNREF(p,sip_destroy_peer); 16663 } else { 16664 char *port = strchr(host, ':'); 16665 if (port) 16666 *port = '\0'; 16667 hp = ast_gethostbyname(host, &ahp); 16668 if (hp) 16669 res = AST_DEVICE_UNKNOWN; 16670 } 16671 16672 return res; 16673 }
static int sip_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 11533 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.
11534 { 11535 int oldsipdebug = sipdebug_console; 11536 if (argc != 3) { 11537 if (argc != 5) 11538 return RESULT_SHOWUSAGE; 11539 else if (strcmp(argv[3], "ip") == 0) 11540 return sip_do_debug_ip(fd, argc, argv); 11541 else if (strcmp(argv[3], "peer") == 0) 11542 return sip_do_debug_peer(fd, argc, argv); 11543 else 11544 return RESULT_SHOWUSAGE; 11545 } 11546 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11547 memset(&debugaddr, 0, sizeof(debugaddr)); 11548 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11549 return RESULT_SUCCESS; 11550 }
static int sip_do_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11552 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.
11553 { 11554 int oldsipdebug = sipdebug_console; 11555 char *newargv[6] = { "sip", "set", "debug", NULL }; 11556 if (argc != 2) { 11557 if (argc != 4) 11558 return RESULT_SHOWUSAGE; 11559 else if (strcmp(argv[2], "ip") == 0) { 11560 newargv[3] = argv[2]; 11561 newargv[4] = argv[3]; 11562 return sip_do_debug_ip(fd, argc + 1, newargv); 11563 } else if (strcmp(argv[2], "peer") == 0) { 11564 newargv[3] = argv[2]; 11565 newargv[4] = argv[3]; 11566 return sip_do_debug_peer(fd, argc + 1, newargv); 11567 } else 11568 return RESULT_SHOWUSAGE; 11569 } 11570 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11571 memset(&debugaddr, 0, sizeof(debugaddr)); 11572 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 11573 return RESULT_SUCCESS; 11574 }
static int sip_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP Debugging in CLI.
Definition at line 11479 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().
11480 { 11481 struct hostent *hp; 11482 struct ast_hostent ahp; 11483 int port = 0; 11484 char *p, *arg; 11485 11486 /* sip set debug ip <ip> */ 11487 if (argc != 5) 11488 return RESULT_SHOWUSAGE; 11489 p = arg = argv[4]; 11490 strsep(&p, ":"); 11491 if (p) 11492 port = atoi(p); 11493 hp = ast_gethostbyname(arg, &ahp); 11494 if (hp == NULL) 11495 return RESULT_SHOWUSAGE; 11496 11497 debugaddr.sin_family = AF_INET; 11498 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 11499 debugaddr.sin_port = htons(port); 11500 if (port == 0) 11501 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 11502 else 11503 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 11504 11505 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11506 11507 return RESULT_SUCCESS; 11508 }
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 11511 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().
11512 { 11513 struct sip_peer *peer; 11514 if (argc != 5) 11515 return RESULT_SHOWUSAGE; 11516 peer = find_peer(argv[4], NULL, 1, 0); 11517 if (peer) { 11518 if (peer->addr.sin_addr.s_addr) { 11519 debugaddr.sin_family = AF_INET; 11520 debugaddr.sin_addr = peer->addr.sin_addr; 11521 debugaddr.sin_port = peer->addr.sin_port; 11522 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 11523 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11524 } else 11525 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]); 11526 ASTOBJ_UNREF(peer,sip_destroy_peer); 11527 } else 11528 ast_cli(fd, "No such peer '%s'\n", argv[4]); 11529 return RESULT_SUCCESS; 11530 }
static int sip_do_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Enable SIP History logging (CLI).
Definition at line 11652 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and TRUE.
11653 { 11654 if (argc != 2) { 11655 return RESULT_SHOWUSAGE; 11656 } 11657 recordhistory = TRUE; 11658 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 11659 return RESULT_SUCCESS; 11660 }
static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 18632 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().
18633 { 18634 reload_config(reason); 18635 18636 /* Prune peers who still are supposed to be deleted */ 18637 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 18638 if (option_debug > 3) 18639 ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n"); 18640 18641 /* Send qualify (OPTIONS) to all peers */ 18642 sip_poke_all_peers(); 18643 18644 /* Register with all services */ 18645 sip_send_all_registers(); 18646 18647 if (option_debug > 3) 18648 ast_log(LOG_DEBUG, "--------------- SIP reload done\n"); 18649 18650 return 0; 18651 }
static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 18431 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().
18432 { 18433 struct sip_pvt *p; 18434 char *mode; 18435 if (data) 18436 mode = (char *)data; 18437 else { 18438 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 18439 return 0; 18440 } 18441 ast_channel_lock(chan); 18442 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 18443 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 18444 ast_channel_unlock(chan); 18445 return 0; 18446 } 18447 p = chan->tech_pvt; 18448 if (!p) { 18449 ast_channel_unlock(chan); 18450 return 0; 18451 } 18452 ast_mutex_lock(&p->lock); 18453 if (!strcasecmp(mode,"info")) { 18454 ast_clear_flag(&p->flags[0], SIP_DTMF); 18455 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 18456 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 18457 } else if (!strcasecmp(mode,"rfc2833")) { 18458 ast_clear_flag(&p->flags[0], SIP_DTMF); 18459 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 18460 p->jointnoncodeccapability |= AST_RTP_DTMF; 18461 } else if (!strcasecmp(mode,"inband")) { 18462 ast_clear_flag(&p->flags[0], SIP_DTMF); 18463 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 18464 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 18465 } else 18466 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 18467 if (p->rtp) 18468 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 18469 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 18470 if (!p->vad) { 18471 p->vad = ast_dsp_new(); 18472 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 18473 } 18474 } else { 18475 if (p->vad) { 18476 ast_dsp_free(p->vad); 18477 p->vad = NULL; 18478 } 18479 } 18480 ast_mutex_unlock(&p->lock); 18481 ast_channel_unlock(chan); 18482 return 0; 18483 }
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 11337 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().
11338 { 11339 int x = 0; 11340 struct sip_history *hist; 11341 static int errmsg = 0; 11342 11343 if (!dialog) 11344 return; 11345 11346 if (!option_debug && !sipdebug) { 11347 if (!errmsg) { 11348 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 11349 errmsg = 1; 11350 } 11351 return; 11352 } 11353 11354 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 11355 if (dialog->subscribed) 11356 ast_log(LOG_DEBUG, " * Subscription\n"); 11357 else 11358 ast_log(LOG_DEBUG, " * SIP Call\n"); 11359 if (dialog->history) 11360 AST_LIST_TRAVERSE(dialog->history, hist, list) 11361 ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); 11362 if (!x) 11363 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 11364 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 11365 }
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 3823 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.
03824 { 03825 int ret = -1; 03826 struct sip_pvt *p; 03827 03828 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug) 03829 ast_log(LOG_DEBUG, "New channel is zombie\n"); 03830 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug) 03831 ast_log(LOG_DEBUG, "Old channel is zombie\n"); 03832 03833 if (!newchan || !newchan->tech_pvt) { 03834 if (!newchan) 03835 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 03836 else 03837 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 03838 return -1; 03839 } 03840 p = newchan->tech_pvt; 03841 03842 if (!p) { 03843 ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n"); 03844 return -1; 03845 } 03846 03847 ast_mutex_lock(&p->lock); 03848 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 03849 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 03850 if (p->owner != oldchan) 03851 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 03852 else { 03853 p->owner = newchan; 03854 /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native 03855 RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be 03856 able to do this if the masquerade happens before the bridge breaks (e.g., AMI 03857 redirect of both channels). Note that a channel can not be masqueraded *into* 03858 a native bridge. So there is no danger that this breaks a native bridge that 03859 should stay up. */ 03860 sip_set_rtp_peer(newchan, NULL, NULL, 0, 0); 03861 ret = 0; 03862 } 03863 if (option_debug > 2) 03864 ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 03865 03866 ast_mutex_unlock(&p->lock); 03867 return ret; 03868 }
static int sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Return SIP UA's codec (part of the RTP interface).
Definition at line 18576 of file chan_sip.c.
References sip_pvt::capability, sip_pvt::jointcapability, and ast_channel::tech_pvt.
18577 { 18578 struct sip_pvt *p = chan->tech_pvt; 18579 return p->jointcapability ? p->jointcapability : p->capability; 18580 }
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 18284 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.
18285 { 18286 struct sip_pvt *p = NULL; 18287 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 18288 18289 if (!(p = chan->tech_pvt)) 18290 return AST_RTP_GET_FAILED; 18291 18292 ast_mutex_lock(&p->lock); 18293 if (!(p->rtp)) { 18294 ast_mutex_unlock(&p->lock); 18295 return AST_RTP_GET_FAILED; 18296 } 18297 18298 *rtp = p->rtp; 18299 18300 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 18301 res = AST_RTP_TRY_PARTIAL; 18302 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 18303 res = AST_RTP_TRY_NATIVE; 18304 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 18305 res = AST_RTP_GET_FAILED; 18306 18307 ast_mutex_unlock(&p->lock); 18308 18309 return res; 18310 }
static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 18149 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.
18150 { 18151 struct sip_pvt *p; 18152 struct ast_udptl *udptl = NULL; 18153 18154 p = chan->tech_pvt; 18155 if (!p) 18156 return NULL; 18157 18158 ast_mutex_lock(&p->lock); 18159 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 18160 udptl = p->udptl; 18161 ast_mutex_unlock(&p->lock); 18162 return udptl; 18163 }
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 18313 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.
18314 { 18315 struct sip_pvt *p = NULL; 18316 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 18317 18318 if (!(p = chan->tech_pvt)) 18319 return AST_RTP_GET_FAILED; 18320 18321 ast_mutex_lock(&p->lock); 18322 if (!(p->vrtp)) { 18323 ast_mutex_unlock(&p->lock); 18324 return AST_RTP_GET_FAILED; 18325 } 18326 18327 *rtp = p->vrtp; 18328 18329 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 18330 res = AST_RTP_TRY_NATIVE; 18331 18332 ast_mutex_unlock(&p->lock); 18333 18334 return res; 18335 }
static int sip_handle_t38_reinvite | ( | struct ast_channel * | chan, | |
struct sip_pvt * | pvt, | |||
int | reinvite | |||
) | [static] |
Handle T38 reinvite.
Definition at line 18201 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().
18202 { 18203 struct sip_pvt *p; 18204 int flag = 0; 18205 18206 p = chan->tech_pvt; 18207 if (!p || !pvt->udptl) 18208 return -1; 18209 18210 /* Setup everything on the other side like offered/responded from first side */ 18211 ast_mutex_lock(&p->lock); 18212 18213 /*! \todo check if this is not set earlier when setting up the PVT. If not 18214 maybe it should move there. */ 18215 p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability; 18216 18217 ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 18218 ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 18219 ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl)); 18220 18221 if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */ 18222 /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects, 18223 not really T38 re-invites which are different. In this 18224 case it's used properly, to see if we can reinvite over 18225 NAT 18226 */ 18227 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 18228 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 18229 flag =1; 18230 } else { 18231 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18232 } 18233 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 18234 if (!p->pendinginvite) { 18235 if (option_debug > 2) { 18236 if (flag) 18237 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)); 18238 else 18239 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)); 18240 } 18241 transmit_reinvite_with_t38_sdp(p); 18242 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18243 if (option_debug > 2) { 18244 if (flag) 18245 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)); 18246 else 18247 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)); 18248 } 18249 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18250 } 18251 } 18252 /* Reset lastrtprx timer */ 18253 p->lastrtprx = p->lastrtptx = time(NULL); 18254 ast_mutex_unlock(&p->lock); 18255 return 0; 18256 } else { /* If we are handling sending 200 OK to the other side of the bridge */ 18257 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 18258 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 18259 flag = 1; 18260 } else { 18261 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18262 } 18263 if (option_debug > 2) { 18264 if (flag) 18265 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)); 18266 else 18267 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)); 18268 } 18269 pvt->t38.state = T38_ENABLED; 18270 p->t38.state = T38_ENABLED; 18271 if (option_debug > 1) { 18272 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 18273 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 18274 } 18275 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 18276 p->lastrtprx = p->lastrtptx = time(NULL); 18277 ast_mutex_unlock(&p->lock); 18278 return 0; 18279 } 18280 }
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 3530 of file chan_sip.c.
References __sip_pretend_ack(), ast_channel::_state, append_history, ast_cause2str(), ast_clear_flag, ast_dsp_free(), AST_FLAG_ZOMBIE, ast_log(), ast_module_unref(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_quality(), AST_SCHED_DEL, ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, sip_pvt::autokillid, sip_pvt::callid, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, INC_CALL_LIMIT, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, sched, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_DEFER_BYE_ON_TRANSFER, SIP_INC_COUNT, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_PAGE2_CALL_ONHOLD, SIP_PENDINGBYE, sip_scheddestroy(), sipdebug, stop_media_flows(), ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, update_call_counter(), sip_pvt::username, sip_pvt::vad, and XMIT_RELIABLE.
03531 { 03532 struct sip_pvt *p = ast->tech_pvt; 03533 int needcancel = FALSE; 03534 int needdestroy = 0; 03535 struct ast_channel *oldowner = ast; 03536 03537 if (!p) { 03538 if (option_debug) 03539 ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n"); 03540 return 0; 03541 } 03542 03543 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 03544 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03545 if (option_debug && sipdebug) 03546 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03547 update_call_counter(p, DEC_CALL_LIMIT); 03548 } 03549 if (option_debug >3) 03550 ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 03551 if (p->autokillid > -1 && sip_cancel_destroy(p)) 03552 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03553 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03554 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 03555 ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY); 03556 p->owner->tech_pvt = NULL; 03557 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 03558 return 0; 03559 } 03560 if (option_debug) { 03561 if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug) 03562 ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 03563 else { 03564 if (option_debug) 03565 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 03566 } 03567 } 03568 if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 03569 ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n"); 03570 03571 ast_mutex_lock(&p->lock); 03572 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 03573 if (option_debug && sipdebug) 03574 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03575 update_call_counter(p, DEC_CALL_LIMIT); 03576 } 03577 03578 /* Determine how to disconnect */ 03579 if (p->owner != ast) { 03580 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 03581 ast_mutex_unlock(&p->lock); 03582 return 0; 03583 } 03584 /* If the call is not UP, we need to send CANCEL instead of BYE */ 03585 if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) { 03586 needcancel = TRUE; 03587 if (option_debug > 3) 03588 ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 03589 } 03590 03591 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 03592 03593 append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->owner->hangupcause) : "Unknown"); 03594 03595 /* Disconnect */ 03596 if (p->vad) 03597 ast_dsp_free(p->vad); 03598 03599 p->owner = NULL; 03600 ast->tech_pvt = NULL; 03601 03602 ast_module_unref(ast_module_info->self); 03603 03604 /* Do not destroy this pvt until we have timeout or 03605 get an answer to the BYE or INVITE/CANCEL 03606 If we get no answer during retransmit period, drop the call anyway. 03607 (Sorry, mother-in-law, you can't deny a hangup by sending 03608 603 declined to BYE...) 03609 */ 03610 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) 03611 needdestroy = 1; /* Set destroy flag at end of this function */ 03612 else if (p->invitestate != INV_CALLING) 03613 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03614 03615 /* Start the process if it's not already started */ 03616 if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 03617 if (needcancel) { /* Outgoing call, not up */ 03618 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03619 /* stop retransmitting an INVITE that has not received a response */ 03620 __sip_pretend_ack(p); 03621 p->invitestate = INV_CANCELLED; 03622 03623 /* if we can't send right now, mark it pending */ 03624 if (p->invitestate == INV_CALLING) { 03625 /* We can't send anything in CALLING state */ 03626 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03627 /* 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. */ 03628 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03629 append_history(p, "DELAY", "Not sending cancel, waiting for timeout"); 03630 } else { 03631 /* Send a new request: CANCEL */ 03632 transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE); 03633 /* Actually don't destroy us yet, wait for the 487 on our original 03634 INVITE, but do set an autodestruct just in case we never get it. */ 03635 needdestroy = 0; 03636 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03637 } 03638 if ( p->initid != -1 ) { 03639 /* channel still up - reverse dec of inUse counter 03640 only if the channel is not auto-congested */ 03641 update_call_counter(p, INC_CALL_LIMIT); 03642 } 03643 } else { /* Incoming call, not up */ 03644 const char *res; 03645 if (ast->hangupcause && (res = hangup_cause2sip(ast->hangupcause))) 03646 transmit_response_reliable(p, res, &p->initreq); 03647 else 03648 transmit_response_reliable(p, "603 Declined", &p->initreq); 03649 p->invitestate = INV_TERMINATED; 03650 } 03651 } else { /* Call is in UP state, send BYE */ 03652 if (!p->pendinginvite) { 03653 char *audioqos = ""; 03654 char *videoqos = ""; 03655 if (p->rtp) 03656 audioqos = ast_rtp_get_quality(p->rtp, NULL); 03657 if (p->vrtp) 03658 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 03659 /* Send a hangup */ 03660 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03661 03662 /* Get RTCP quality before end of call */ 03663 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 03664 if (p->rtp) 03665 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 03666 if (p->vrtp) 03667 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 03668 } 03669 if (p->rtp && oldowner) 03670 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); 03671 if (p->vrtp && oldowner) 03672 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos); 03673 } else { 03674 /* Note we will need a BYE when this all settles out 03675 but we can't send one while we have "INVITE" outstanding. */ 03676 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03677 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 03678 AST_SCHED_DEL(sched, p->waitid); 03679 if (sip_cancel_destroy(p)) 03680 ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); 03681 } 03682 } 03683 } 03684 if (needdestroy) 03685 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 03686 ast_mutex_unlock(&p->lock); 03687 return 0; 03688 }
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 3939 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.
03940 { 03941 struct sip_pvt *p = ast->tech_pvt; 03942 int res = 0; 03943 03944 ast_mutex_lock(&p->lock); 03945 switch(condition) { 03946 case AST_CONTROL_RINGING: 03947 if (ast->_state == AST_STATE_RING) { 03948 p->invitestate = INV_EARLY_MEDIA; 03949 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 03950 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 03951 /* Send 180 ringing if out-of-band seems reasonable */ 03952 transmit_response(p, "180 Ringing", &p->initreq); 03953 ast_set_flag(&p->flags[0], SIP_RINGING); 03954 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 03955 break; 03956 } else { 03957 /* Well, if it's not reasonable, just send in-band */ 03958 } 03959 } 03960 res = -1; 03961 break; 03962 case AST_CONTROL_BUSY: 03963 if (ast->_state != AST_STATE_UP) { 03964 transmit_response_reliable(p, "486 Busy Here", &p->initreq); 03965 p->invitestate = INV_COMPLETED; 03966 sip_alreadygone(p); 03967 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03968 break; 03969 } 03970 res = -1; 03971 break; 03972 case AST_CONTROL_CONGESTION: 03973 if (ast->_state != AST_STATE_UP) { 03974 transmit_response_reliable(p, "503 Service Unavailable", &p->initreq); 03975 p->invitestate = INV_COMPLETED; 03976 sip_alreadygone(p); 03977 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03978 break; 03979 } 03980 res = -1; 03981 break; 03982 case AST_CONTROL_PROCEEDING: 03983 if ((ast->_state != AST_STATE_UP) && 03984 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03985 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03986 transmit_response(p, "100 Trying", &p->initreq); 03987 p->invitestate = INV_PROCEEDING; 03988 break; 03989 } 03990 res = -1; 03991 break; 03992 case AST_CONTROL_PROGRESS: 03993 if ((ast->_state != AST_STATE_UP) && 03994 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03995 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03996 p->invitestate = INV_EARLY_MEDIA; 03997 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03998 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03999 break; 04000 } 04001 res = -1; 04002 break; 04003 case AST_CONTROL_HOLD: 04004 ast_rtp_new_source(p->rtp); 04005 ast_moh_start(ast, data, p->mohinterpret); 04006 break; 04007 case AST_CONTROL_UNHOLD: 04008 ast_rtp_new_source(p->rtp); 04009 ast_moh_stop(ast); 04010 break; 04011 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 04012 if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 04013 transmit_info_with_vidupdate(p); 04014 /* ast_rtcp_send_h261fur(p->vrtp); */ 04015 } else 04016 res = -1; 04017 break; 04018 case AST_CONTROL_SRCUPDATE: 04019 ast_rtp_new_source(p->rtp); 04020 break; 04021 case -1: 04022 res = -1; 04023 break; 04024 default: 04025 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 04026 res = -1; 04027 break; 04028 } 04029 ast_mutex_unlock(&p->lock); 04030 return res; 04031 }
static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 1773 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().
01774 { 01775 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT"; 01776 }
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 4039 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().
04040 { 04041 struct ast_channel *tmp; 04042 struct ast_variable *v = NULL; 04043 int fmt; 04044 int what; 04045 int needvideo = 0, video = 0; 04046 char *decoded_exten; 04047 04048 if (option_debug != 0) { 04049 ast_verbose(VERBOSE_PREFIX_3 "NEW SIP CHANNEL, title: <%s>\n", title?title:"Null"); 04050 ast_verbose(VERBOSE_PREFIX_3 "from: %s\n", i->from); 04051 ast_verbose(VERBOSE_PREFIX_3 "username: <%s>\n", i->username); 04052 ast_verbose(VERBOSE_PREFIX_3 "peername: <%s>\n", i->peername); 04053 ast_verbose(VERBOSE_PREFIX_3 "fromdomain: %s\n", i->fromdomain); 04054 ast_verbose(VERBOSE_PREFIX_3 "fromuser: %s\n", i->fromuser); 04055 ast_verbose(VERBOSE_PREFIX_3 "fromname: %s\n", i->fromname); 04056 ast_verbose(VERBOSE_PREFIX_3 "fullcontact: %s\n", i->fullcontact); 04057 } 04058 04059 { 04060 char my_name[128]; /* pick a good name */ 04061 const char *f, *fromdomain = NULL; 04062 04063 if (!ast_strlen_zero(i->fromdomain) && strchr(i->fromdomain,':')) 04064 fromdomain = strchr(i->fromdomain,':') + 1; /* skip ':' */ 04065 else 04066 fromdomain = i->fromdomain; 04067 04068 if (!ast_strlen_zero(i->username)) { 04069 if (!ast_strlen_zero(title) && strcmp(i->username, title)) { 04070 /* title not empty and different from username */ 04071 snprintf(my_name, sizeof(my_name), "%s@%s", i->username, title); 04072 } else { 04073 /* username not empty, title is empty or equal to username */ 04074 snprintf(my_name, sizeof(my_name), "%s", i->username); 04075 } 04076 } else { /* username empty */ 04077 if (!ast_strlen_zero(i->peername)) { 04078 /* call from unregisted peer */ 04079 snprintf(my_name, sizeof(my_name), "%s", i->peername); 04080 } else { /* username and peername empty */ 04081 if (!ast_strlen_zero(title)) { /* title not empty */ 04082 snprintf(my_name, sizeof(my_name), "%s", title); 04083 } else if (!ast_strlen_zero(i->from)) { /* title empty, From: not empty */ 04084 f = i->from; 04085 if (!strncmp(f, "sip:", 4)) 04086 f += 4; 04087 snprintf(my_name, sizeof(my_name), "%s", f); 04088 } else { /* fallback to fromdomain */ 04089 snprintf(my_name, sizeof(my_name), "%s", fromdomain); 04090 } 04091 } 04092 } 04093 ast_mutex_unlock(&i->lock); 04094 /* Don't hold a sip pvt lock while we allocate a channel */ 04095 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); 04096 04097 } 04098 if (!tmp) { 04099 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 04100 ast_mutex_lock(&i->lock); 04101 return NULL; 04102 } 04103 ast_mutex_lock(&i->lock); 04104 04105 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO) 04106 tmp->tech = &sip_tech_info; 04107 else 04108 tmp->tech = &sip_tech; 04109 04110 /* Select our native format based on codec preference until we receive 04111 something from another device to the contrary. */ 04112 if (i->jointcapability) { /* The joint capabilities of us and peer */ 04113 what = i->jointcapability; 04114 video = i->jointcapability & AST_FORMAT_VIDEO_MASK; 04115 } else if (i->capability) { /* Our configured capability for this peer */ 04116 what = i->capability; 04117 video = i->capability & AST_FORMAT_VIDEO_MASK; 04118 } else { 04119 what = global_capability; /* Global codec support */ 04120 video = global_capability & AST_FORMAT_VIDEO_MASK; 04121 } 04122 04123 /* Set the native formats for audio and merge in video */ 04124 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video; 04125 if (option_debug > 2) { 04126 char buf[SIPBUFSIZE]; 04127 ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats)); 04128 ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability)); 04129 ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability)); 04130 ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1))); 04131 if (i->prefcodec) 04132 ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec)); 04133 } 04134 04135 /* XXX Why are we choosing a codec from the native formats?? */ 04136 fmt = ast_best_codec(tmp->nativeformats); 04137 04138 /* If we have a prefcodec setting, we have an inbound channel that set a 04139 preferred format for this call. Otherwise, we check the jointcapability 04140 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 04141 */ 04142 if (i->vrtp) { 04143 if (i->prefcodec) 04144 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 04145 else 04146 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 04147 } 04148 04149 if (option_debug > 2) { 04150 if (needvideo) 04151 ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n"); 04152 else 04153 ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n"); 04154 } 04155 04156 04157 04158 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 04159 i->vad = ast_dsp_new(); 04160 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 04161 if (global_relaxdtmf) 04162 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 04163 } 04164 if (i->rtp) { 04165 tmp->fds[0] = ast_rtp_fd(i->rtp); 04166 tmp->fds[1] = ast_rtcp_fd(i->rtp); 04167 } 04168 if (needvideo && i->vrtp) { 04169 tmp->fds[2] = ast_rtp_fd(i->vrtp); 04170 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 04171 } 04172 if (i->udptl) { 04173 tmp->fds[5] = ast_udptl_fd(i->udptl); 04174 } 04175 if (state == AST_STATE_RING) 04176 tmp->rings = 1; 04177 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 04178 tmp->writeformat = fmt; 04179 tmp->rawwriteformat = fmt; 04180 tmp->readformat = fmt; 04181 tmp->rawreadformat = fmt; 04182 tmp->tech_pvt = i; 04183 04184 tmp->callgroup = i->callgroup; 04185 tmp->pickupgroup = i->pickupgroup; 04186 tmp->cid.cid_pres = i->callingpres; 04187 if (!ast_strlen_zero(i->accountcode)) 04188 ast_string_field_set(tmp, accountcode, i->accountcode); 04189 if (i->amaflags) 04190 tmp->amaflags = i->amaflags; 04191 if (!ast_strlen_zero(i->language)) 04192 ast_string_field_set(tmp, language, i->language); 04193 i->owner = tmp; 04194 ast_module_ref(ast_module_info->self); 04195 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 04196 /*Since it is valid to have extensions in the dialplan that have unescaped characters in them 04197 * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt 04198 * structure so that there aren't issues when forming URI's 04199 */ 04200 decoded_exten = ast_strdupa(i->exten); 04201 ast_uri_decode(decoded_exten); 04202 ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten)); 04203 04204 /* Don't use ast_set_callerid() here because it will 04205 * generate an unnecessary NewCallerID event */ 04206 tmp->cid.cid_ani = ast_strdup(i->cid_num); 04207 if (!ast_strlen_zero(i->rdnis)) 04208 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 04209 04210 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 04211 tmp->cid.cid_dnid = ast_strdup(i->exten); 04212 04213 tmp->priority = 1; 04214 if (!ast_strlen_zero(i->uri)) 04215 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 04216 if (!ast_strlen_zero(i->domain)) 04217 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 04218 if (!ast_strlen_zero(i->useragent)) 04219 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 04220 if (!ast_strlen_zero(i->callid)) 04221 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 04222 if (i->rtp) 04223 ast_jb_configure(tmp, &global_jbconf); 04224 04225 /* If the INVITE contains T.38 SDP information set the proper channel variable so a created outgoing call will also have T.38 */ 04226 if (i->udptl && i->t38.state == T38_PEER_DIRECT) 04227 pbx_builtin_setvar_helper(tmp, "_T38CALL", "1"); 04228 04229 /* Set channel variables for this call from configuration */ 04230 for (v = i->chanvars ; v ; v = v->next) 04231 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04232 04233 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 04234 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04235 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 04236 ast_hangup(tmp); 04237 tmp = NULL; 04238 } 04239 04240 if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY)) 04241 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 04242 04243 return tmp; 04244 }
static int sip_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP Debugging in CLI.
Definition at line 11633 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11634 { 11635 if (argc != 4) 11636 return RESULT_SHOWUSAGE; 11637 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11638 ast_cli(fd, "SIP Debugging Disabled\n"); 11639 return RESULT_SUCCESS; 11640 }
static int sip_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 11642 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11643 { 11644 if (argc != 3) 11645 return RESULT_SHOWUSAGE; 11646 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11647 ast_cli(fd, "SIP Debugging Disabled\n"); 11648 return RESULT_SUCCESS; 11649 }
static int sip_no_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Disable SIP History logging (CLI).
Definition at line 11663 of file chan_sip.c.
References ast_cli(), FALSE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
11664 { 11665 if (argc != 3) { 11666 return RESULT_SHOWUSAGE; 11667 } 11668 recordhistory = FALSE; 11669 ast_cli(fd, "SIP History Recording Disabled\n"); 11670 return RESULT_SUCCESS; 11671 }
static int sip_notify | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Cli command to send SIP notify to peer.
Definition at line 11577 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.
11578 { 11579 struct ast_variable *varlist; 11580 int i; 11581 11582 if (argc < 4) 11583 return RESULT_SHOWUSAGE; 11584 11585 if (!notify_types) { 11586 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 11587 return RESULT_FAILURE; 11588 } 11589 11590 varlist = ast_variable_browse(notify_types, argv[2]); 11591 11592 if (!varlist) { 11593 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 11594 return RESULT_FAILURE; 11595 } 11596 11597 for (i = 3; i < argc; i++) { 11598 struct sip_pvt *p; 11599 struct sip_request req; 11600 struct ast_variable *var; 11601 11602 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { 11603 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 11604 return RESULT_FAILURE; 11605 } 11606 11607 if (create_addr(p, argv[i])) { 11608 /* Maybe they're not registered, etc. */ 11609 sip_destroy(p); 11610 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 11611 continue; 11612 } 11613 11614 initreqprep(&req, p, SIP_NOTIFY); 11615 11616 for (var = varlist; var; var = var->next) 11617 add_header(&req, var->name, ast_unescape_semicolon(var->value)); 11618 11619 /* Recalculate our side, and recalculate Call ID */ 11620 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 11621 p->ourip = __ourip; 11622 build_via(p); 11623 build_callid_pvt(p); 11624 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 11625 transmit_sip_request(p, &req); 11626 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11627 } 11628 11629 return RESULT_SUCCESS; 11630 }
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 13413 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().
13414 { 13415 struct sip_dual *d; 13416 struct ast_channel *transferee, *transferer; 13417 /* Chan2m: The transferer, chan1m: The transferee */ 13418 pthread_t th; 13419 13420 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 13421 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); 13422 if ((!transferer) || (!transferee)) { 13423 if (transferee) { 13424 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13425 ast_hangup(transferee); 13426 } 13427 if (transferer) { 13428 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13429 ast_hangup(transferer); 13430 } 13431 return -1; 13432 } 13433 13434 /* Make formats okay */ 13435 transferee->readformat = chan1->readformat; 13436 transferee->writeformat = chan1->writeformat; 13437 13438 /* Prepare for taking over the channel */ 13439 ast_channel_masquerade(transferee, chan1); 13440 13441 /* Setup the extensions and such */ 13442 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 13443 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 13444 transferee->priority = chan1->priority; 13445 13446 /* We make a clone of the peer channel too, so we can play 13447 back the announcement */ 13448 13449 /* Make formats okay */ 13450 transferer->readformat = chan2->readformat; 13451 transferer->writeformat = chan2->writeformat; 13452 13453 /* Prepare for taking over the channel. Go ahead and grab this channel 13454 * lock here to avoid a deadlock with callbacks into the channel driver 13455 * that hold the channel lock and want the pvt lock. */ 13456 while (ast_channel_trylock(chan2)) { 13457 struct sip_pvt *pvt = chan2->tech_pvt; 13458 DEADLOCK_AVOIDANCE(&pvt->lock); 13459 } 13460 ast_channel_masquerade(transferer, chan2); 13461 ast_channel_unlock(chan2); 13462 13463 /* Setup the extensions and such */ 13464 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 13465 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 13466 transferer->priority = chan2->priority; 13467 13468 ast_channel_lock(transferer); 13469 if (ast_do_masquerade(transferer)) { 13470 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 13471 ast_channel_unlock(transferer); 13472 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13473 ast_hangup(transferer); 13474 return -1; 13475 } 13476 ast_channel_unlock(transferer); 13477 if (!transferer || !transferee) { 13478 if (!transferer) { 13479 if (option_debug) 13480 ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n"); 13481 } 13482 if (!transferee) { 13483 if (option_debug) 13484 ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n"); 13485 } 13486 return -1; 13487 } 13488 if ((d = ast_calloc(1, sizeof(*d)))) { 13489 pthread_attr_t attr; 13490 13491 pthread_attr_init(&attr); 13492 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 13493 13494 /* Save original request for followup */ 13495 copy_request(&d->req, req); 13496 d->chan1 = transferee; /* Transferee */ 13497 d->chan2 = transferer; /* Transferer */ 13498 d->seqno = seqno; 13499 if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) { 13500 /* Could not start thread */ 13501 free(d); /* We don't need it anymore. If thread is created, d will be free'd 13502 by sip_park_thread() */ 13503 pthread_attr_destroy(&attr); 13504 return 0; 13505 } 13506 pthread_attr_destroy(&attr); 13507 } 13508 return -1; 13509 }
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 13346 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().
13347 { 13348 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 13349 struct sip_dual *d; 13350 struct sip_request req; 13351 int ext; 13352 int res; 13353 13354 d = stuff; 13355 transferee = d->chan1; 13356 transferer = d->chan2; 13357 copy_request(&req, &d->req); 13358 13359 if (!transferee || !transferer) { 13360 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 13361 return NULL; 13362 } 13363 if (option_debug > 3) 13364 ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 13365 13366 ast_channel_lock(transferee); 13367 if (ast_do_masquerade(transferee)) { 13368 ast_log(LOG_WARNING, "Masquerade failed.\n"); 13369 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 13370 ast_channel_unlock(transferee); 13371 return NULL; 13372 } 13373 ast_channel_unlock(transferee); 13374 13375 res = ast_park_call(transferee, transferer, 0, &ext); 13376 13377 13378 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 13379 if (!res) { 13380 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 13381 } else { 13382 /* Then tell the transferer what happened */ 13383 sprintf(buf, "Call parked on extension '%d'", ext); 13384 transmit_message_with_text(transferer->tech_pvt, buf); 13385 } 13386 #endif 13387 13388 /* Any way back to the current call??? */ 13389 /* Transmit response to the REFER request */ 13390 transmit_response(transferer->tech_pvt, "202 Accepted", &req); 13391 if (!res) { 13392 /* Transfer succeeded */ 13393 append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext); 13394 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 13395 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 13396 ast_hangup(transferer); /* This will cause a BYE */ 13397 if (option_debug) 13398 ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext); 13399 } else { 13400 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 13401 append_history(transferer->tech_pvt, "SIPpark","Parking failed\n"); 13402 if (option_debug) 13403 ast_log(LOG_DEBUG, "SIP Call parked failed \n"); 13404 /* Do not hangup call */ 13405 } 13406 free(d); 13407 return NULL; 13408 }
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 8749 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().
08750 { 08751 struct sip_peer *peer = find_peer(p->peername, NULL, 1, 0); 08752 08753 if (!peer) 08754 return; 08755 08756 /* If they put someone on hold, increment the value... otherwise decrement it */ 08757 if (hold) 08758 peer->onHold++; 08759 else 08760 peer->onHold--; 08761 08762 /* Request device state update */ 08763 ast_device_state_changed("SIP/%s", peer->name); 08764 08765 return; 08766 }
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 18586 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().
18587 { 18588 int ms = 0; 18589 18590 if (!speerobjs) /* No peers, just give up */ 18591 return; 18592 18593 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 18594 ASTOBJ_WRLOCK(iterator); 18595 if (!AST_SCHED_DEL(sched, iterator->pokeexpire)) { 18596 struct sip_peer *peer_ptr = iterator; 18597 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 18598 } 18599 ms += 100; 18600 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, ASTOBJ_REF(iterator)); 18601 if (iterator->pokeexpire == -1) { 18602 struct sip_peer *peer_ptr = iterator; 18603 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 18604 } 18605 ASTOBJ_UNLOCK(iterator); 18606 } while (0) 18607 ); 18608 }
static int sip_poke_noanswer | ( | const void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 16458 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), AST_SCHED_DEL, ASTOBJ_UNREF, sip_peer::call, DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::name, sip_peer::pokeexpire, sched, sip_destroy(), sip_destroy_peer(), and sip_poke_peer_s().
Referenced by sip_poke_peer().
16459 { 16460 struct sip_peer *peer = (struct sip_peer *)data; 16461 16462 peer->pokeexpire = -1; 16463 if (peer->lastms > -1) { 16464 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 16465 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 16466 } 16467 if (peer->call) 16468 sip_destroy(peer->call); 16469 peer->call = NULL; 16470 peer->lastms = -1; 16471 ast_device_state_changed("SIP/%s", peer->name); 16472 16473 /* This function gets called one place outside of the scheduler ... */ 16474 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16475 struct sip_peer *peer_ptr = peer; 16476 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16477 } 16478 16479 /* There is no need to ASTOBJ_REF() here. Just let the scheduled callback 16480 * inherit the reference that the current callback already has. */ 16481 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 16482 if (peer->pokeexpire == -1) { 16483 ASTOBJ_UNREF(peer, sip_destroy_peer); 16484 } 16485 16486 return 0; 16487 }
static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 16492 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 parse_register_contact(), reg_source_db(), and sip_poke_peer_s().
16493 { 16494 struct sip_pvt *p; 16495 int xmitres = 0; 16496 16497 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 16498 /* IF we have no IP, or this isn't to be monitored, return 16499 imeediately after clearing things out */ 16500 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16501 struct sip_peer *peer_ptr = peer; 16502 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16503 } 16504 peer->lastms = 0; 16505 peer->call = NULL; 16506 return 0; 16507 } 16508 if (peer->call) { 16509 if (sipdebug) 16510 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 16511 sip_destroy(peer->call); 16512 } 16513 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS))) 16514 return -1; 16515 16516 p->sa = peer->addr; 16517 p->recv = peer->addr; 16518 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 16519 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 16520 16521 /* Send OPTIONs to peer's fullcontact */ 16522 if (!ast_strlen_zero(peer->fullcontact)) 16523 ast_string_field_set(p, fullcontact, peer->fullcontact); 16524 16525 if (!ast_strlen_zero(peer->tohost)) 16526 ast_string_field_set(p, tohost, peer->tohost); 16527 else 16528 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 16529 16530 /* Recalculate our side, and recalculate Call ID */ 16531 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16532 p->ourip = __ourip; 16533 build_via(p); 16534 build_callid_pvt(p); 16535 16536 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16537 struct sip_peer *peer_ptr = peer; 16538 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16539 } 16540 16541 p->relatedpeer = ASTOBJ_REF(peer); 16542 ast_set_flag(&p->flags[0], SIP_OUTGOING); 16543 #ifdef VOCAL_DATA_HACK 16544 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 16545 xmitres = transmit_invite(p, SIP_INVITE, 0, 2); 16546 #else 16547 xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); 16548 #endif 16549 gettimeofday(&peer->ps, NULL); 16550 if (xmitres == XMIT_ERROR) { 16551 sip_poke_noanswer(ASTOBJ_REF(peer)); /* Immediately unreachable, network problems */ 16552 } else { 16553 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) { 16554 struct sip_peer *peer_ptr = peer; 16555 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16556 } 16557 peer->pokeexpire = ast_sched_add(sched, peer->maxms * 2, sip_poke_noanswer, ASTOBJ_REF(peer)); 16558 if (peer->pokeexpire == -1) { 16559 struct sip_peer *peer_ptr = peer; 16560 ASTOBJ_UNREF(peer_ptr, sip_destroy_peer); 16561 } 16562 } 16563 16564 return 0; 16565 }
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 8095 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().
08096 { 08097 struct sip_peer *peer = (struct sip_peer *) data; 08098 08099 peer->pokeexpire = -1; 08100 08101 sip_poke_peer(peer); 08102 08103 ASTOBJ_UNREF(peer, sip_destroy_peer); 08104 08105 return 0; 08106 }
static int sip_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 10357 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.
10358 { 10359 struct sip_peer *peer; 10360 struct sip_user *user; 10361 int pruneuser = FALSE; 10362 int prunepeer = FALSE; 10363 int multi = FALSE; 10364 char *name = NULL; 10365 regex_t regexbuf; 10366 10367 switch (argc) { 10368 case 4: 10369 if (!strcasecmp(argv[3], "user")) 10370 return RESULT_SHOWUSAGE; 10371 if (!strcasecmp(argv[3], "peer")) 10372 return RESULT_SHOWUSAGE; 10373 if (!strcasecmp(argv[3], "like")) 10374 return RESULT_SHOWUSAGE; 10375 if (!strcasecmp(argv[3], "all")) { 10376 multi = TRUE; 10377 pruneuser = prunepeer = TRUE; 10378 } else { 10379 pruneuser = prunepeer = TRUE; 10380 name = argv[3]; 10381 } 10382 break; 10383 case 5: 10384 if (!strcasecmp(argv[4], "like")) 10385 return RESULT_SHOWUSAGE; 10386 if (!strcasecmp(argv[3], "all")) 10387 return RESULT_SHOWUSAGE; 10388 if (!strcasecmp(argv[3], "like")) { 10389 multi = TRUE; 10390 name = argv[4]; 10391 pruneuser = prunepeer = TRUE; 10392 } else if (!strcasecmp(argv[3], "user")) { 10393 pruneuser = TRUE; 10394 if (!strcasecmp(argv[4], "all")) 10395 multi = TRUE; 10396 else 10397 name = argv[4]; 10398 } else if (!strcasecmp(argv[3], "peer")) { 10399 prunepeer = TRUE; 10400 if (!strcasecmp(argv[4], "all")) 10401 multi = TRUE; 10402 else 10403 name = argv[4]; 10404 } else 10405 return RESULT_SHOWUSAGE; 10406 break; 10407 case 6: 10408 if (strcasecmp(argv[4], "like")) 10409 return RESULT_SHOWUSAGE; 10410 if (!strcasecmp(argv[3], "user")) { 10411 pruneuser = TRUE; 10412 name = argv[5]; 10413 } else if (!strcasecmp(argv[3], "peer")) { 10414 prunepeer = TRUE; 10415 name = argv[5]; 10416 } else 10417 return RESULT_SHOWUSAGE; 10418 break; 10419 default: 10420 return RESULT_SHOWUSAGE; 10421 } 10422 10423 if (multi && name) { 10424 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 10425 return RESULT_SHOWUSAGE; 10426 } 10427 10428 if (multi) { 10429 if (prunepeer) { 10430 int pruned = 0; 10431 10432 ASTOBJ_CONTAINER_WRLOCK(&peerl); 10433 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 10434 ASTOBJ_RDLOCK(iterator); 10435 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10436 ASTOBJ_UNLOCK(iterator); 10437 continue; 10438 }; 10439 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10440 ASTOBJ_MARK(iterator); 10441 pruned++; 10442 } 10443 ASTOBJ_UNLOCK(iterator); 10444 } while (0) ); 10445 if (pruned) { 10446 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 10447 ast_cli(fd, "%d peers pruned.\n", pruned); 10448 } else 10449 ast_cli(fd, "No peers found to prune.\n"); 10450 ASTOBJ_CONTAINER_UNLOCK(&peerl); 10451 } 10452 if (pruneuser) { 10453 int pruned = 0; 10454 10455 ASTOBJ_CONTAINER_WRLOCK(&userl); 10456 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10457 ASTOBJ_RDLOCK(iterator); 10458 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10459 ASTOBJ_UNLOCK(iterator); 10460 continue; 10461 }; 10462 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10463 ASTOBJ_MARK(iterator); 10464 pruned++; 10465 } 10466 ASTOBJ_UNLOCK(iterator); 10467 } while (0) ); 10468 if (pruned) { 10469 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 10470 ast_cli(fd, "%d users pruned.\n", pruned); 10471 } else 10472 ast_cli(fd, "No users found to prune.\n"); 10473 ASTOBJ_CONTAINER_UNLOCK(&userl); 10474 } 10475 } else { 10476 if (prunepeer) { 10477 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 10478 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10479 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 10480 ASTOBJ_CONTAINER_LINK(&peerl, peer); 10481 } else 10482 ast_cli(fd, "Peer '%s' pruned.\n", name); 10483 ASTOBJ_UNREF(peer, sip_destroy_peer); 10484 } else 10485 ast_cli(fd, "Peer '%s' not found.\n", name); 10486 } 10487 if (pruneuser) { 10488 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 10489 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 10490 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 10491 ASTOBJ_CONTAINER_LINK(&userl, user); 10492 } else 10493 ast_cli(fd, "User '%s' pruned.\n", name); 10494 ASTOBJ_UNREF(user, sip_destroy_user); 10495 } else 10496 ast_cli(fd, "User '%s' not found.\n", name); 10497 } 10498 } 10499 10500 return RESULT_SUCCESS; 10501 }
static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static] |
Read SIP RTP from channel.
Definition at line 4447 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().
04448 { 04449 struct ast_frame *fr; 04450 struct sip_pvt *p = ast->tech_pvt; 04451 int faxdetected = FALSE; 04452 04453 ast_mutex_lock(&p->lock); 04454 fr = sip_rtp_read(ast, p, &faxdetected); 04455 p->lastrtprx = time(NULL); 04456 04457 /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */ 04458 /* 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 */ 04459 if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) { 04460 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 04461 if (!p->pendinginvite) { 04462 if (option_debug > 2) 04463 ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name); 04464 p->t38.state = T38_LOCAL_REINVITE; 04465 transmit_reinvite_with_t38_sdp(p); 04466 if (option_debug > 1) 04467 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name); 04468 } 04469 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04470 if (option_debug > 2) 04471 ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name); 04472 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04473 } 04474 } 04475 04476 /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */ 04477 if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) { 04478 fr = &ast_null_frame; 04479 } 04480 04481 ast_mutex_unlock(&p->lock); 04482 return fr; 04483 }
static struct sockaddr_in * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static] |
The real destination address for a write.
Definition at line 1767 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().
01768 { 01769 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa; 01770 }
static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 7900 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().
07901 { 07902 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 07903 return p->refer ? 1 : 0; 07904 }
static int sip_reg_timeout | ( | const void * | data | ) | [static] |
Registration timeout, register again.
Definition at line 7643 of file chan_sip.c.
References __sip_pretend_ack(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, EVENT_FLAG_SYSTEM, sip_pvt::flags, sip_registry::hostname, sip_pvt::lock, LOG_NOTICE, manager_event(), REG_STATE_FAILED, REG_STATE_UNREGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), SIP_NEEDDESTROY, SIP_REGISTER, sip_registry_destroy(), sip_registry::timeout, transmit_register(), and sip_registry::username.
Referenced by transmit_register().
07644 { 07645 07646 /* if we are here, our registration timed out, so we'll just do it over */ 07647 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 07648 struct sip_pvt *p; 07649 int res; 07650 07651 /* if we couldn't get a reference to the registry object, punt */ 07652 if (!r) 07653 return 0; 07654 07655 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 07656 if (r->call) { 07657 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 07658 in the single SIP manager thread. */ 07659 p = r->call; 07660 ast_mutex_lock(&p->lock); 07661 if (p->registry) 07662 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 07663 r->call = NULL; 07664 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 07665 /* Pretend to ACK anything just in case */ 07666 __sip_pretend_ack(p); 07667 ast_mutex_unlock(&p->lock); 07668 } 07669 /* If we have a limit, stop registration and give up */ 07670 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 07671 /* Ok, enough is enough. Don't try any more */ 07672 /* We could add an external notification here... 07673 steal it from app_voicemail :-) */ 07674 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 07675 r->regstate = REG_STATE_FAILED; 07676 } else { 07677 r->regstate = REG_STATE_UNREGISTERED; 07678 r->timeout = -1; 07679 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 07680 } 07681 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)); 07682 ASTOBJ_UNREF(r, sip_registry_destroy); 07683 return 0; 07684 }
static int sip_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 4778 of file chan_sip.c.
References ast_calloc, ast_copy_string(), ast_log(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, sip_registry::authuser, sip_registry::contact, FALSE, free, hostname, INITIAL_CSEQ, LOG_ERROR, regl, secret, sip_registry_destroy(), and username.
04779 { 04780 struct sip_registry *reg; 04781 int portnum = 0; 04782 char username[256] = ""; 04783 char *hostname=NULL, *secret=NULL, *authuser=NULL; 04784 char *porta=NULL; 04785 char *contact=NULL; 04786 04787 if (!value) 04788 return -1; 04789 ast_copy_string(username, value, sizeof(username)); 04790 /* First split around the last '@' then parse the two components. */ 04791 hostname = strrchr(username, '@'); /* allow @ in the first part */ 04792 if (hostname) 04793 *hostname++ = '\0'; 04794 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 04795 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 04796 return -1; 04797 } 04798 /* split user[:secret[:authuser]] */ 04799 secret = strchr(username, ':'); 04800 if (secret) { 04801 *secret++ = '\0'; 04802 authuser = strchr(secret, ':'); 04803 if (authuser) 04804 *authuser++ = '\0'; 04805 } 04806 /* split host[:port][/contact] */ 04807 contact = strchr(hostname, '/'); 04808 if (contact) 04809 *contact++ = '\0'; 04810 if (ast_strlen_zero(contact)) 04811 contact = "s"; 04812 porta = strchr(hostname, ':'); 04813 if (porta) { 04814 *porta++ = '\0'; 04815 portnum = atoi(porta); 04816 if (portnum == 0) { 04817 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 04818 return -1; 04819 } 04820 } 04821 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 04822 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 04823 return -1; 04824 } 04825 04826 if (ast_string_field_init(reg, 256)) { 04827 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 04828 free(reg); 04829 return -1; 04830 } 04831 04832 regobjs++; 04833 ASTOBJ_INIT(reg); 04834 ast_string_field_set(reg, contact, contact); 04835 if (!ast_strlen_zero(username)) 04836 ast_string_field_set(reg, username, username); 04837 if (hostname) 04838 ast_string_field_set(reg, hostname, hostname); 04839 if (authuser) 04840 ast_string_field_set(reg, authuser, authuser); 04841 if (secret) 04842 ast_string_field_set(reg, secret, secret); 04843 reg->expire = -1; 04844 reg->timeout = -1; 04845 reg->refresh = default_expiry; 04846 reg->portno = portnum; 04847 reg->callid_valid = FALSE; 04848 reg->ocseq = INITIAL_CSEQ; 04849 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 04850 ASTOBJ_UNREF(reg,sip_registry_destroy); 04851 return 0; 04852 }
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 3079 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().
03080 { 03081 /* Really delete */ 03082 if (option_debug > 2) 03083 ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 03084 03085 if (reg->call) { 03086 /* Clear registry before destroying to ensure 03087 we don't get reentered trying to grab the registry lock */ 03088 reg->call->registry = NULL; 03089 if (option_debug > 2) 03090 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 03091 sip_destroy(reg->call); 03092 } 03093 AST_SCHED_DEL(sched, reg->expire); 03094 AST_SCHED_DEL(sched, reg->timeout); 03095 ast_string_field_free_memory(reg); 03096 regobjs--; 03097 free(reg); 03098 03099 }
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 12306 of file chan_sip.c.
References ast_set_flag, sip_pvt::flags, SIP_NEEDREINVITE, and sip_pvt::waitid.
Referenced by handle_response_invite().
12307 { 12308 struct sip_pvt *p = (struct sip_pvt *) data; 12309 12310 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 12311 p->waitid = -1; 12312 return 0; 12313 }
static int sip_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Force reload of module from cli.
Definition at line 18654 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().
18655 { 18656 ast_mutex_lock(&sip_reload_lock); 18657 if (sip_reloading) 18658 ast_verbose("Previous SIP reload not yet done\n"); 18659 else { 18660 sip_reloading = TRUE; 18661 if (fd) 18662 sip_reloadreason = CHANNEL_CLI_RELOAD; 18663 else 18664 sip_reloadreason = CHANNEL_MODULE_RELOAD; 18665 } 18666 ast_mutex_unlock(&sip_reload_lock); 18667 restart_monitor(); 18668 18669 return 0; 18670 }
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 16677 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.
16678 { 16679 int oldformat; 16680 struct sip_pvt *p; 16681 struct ast_channel *tmpc = NULL; 16682 char *ext, *host; 16683 char tmp[256]; 16684 char *dest = data; 16685 16686 oldformat = format; 16687 if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { 16688 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)); 16689 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 16690 return NULL; 16691 } 16692 if (option_debug) 16693 ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 16694 16695 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { 16696 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data); 16697 *cause = AST_CAUSE_SWITCH_CONGESTION; 16698 return NULL; 16699 } 16700 16701 ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL); 16702 16703 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 16704 sip_destroy(p); 16705 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 16706 *cause = AST_CAUSE_SWITCH_CONGESTION; 16707 return NULL; 16708 } 16709 16710 ast_copy_string(tmp, dest, sizeof(tmp)); 16711 host = strchr(tmp, '@'); 16712 if (host) { 16713 *host++ = '\0'; 16714 ext = tmp; 16715 } else { 16716 ext = strchr(tmp, '/'); 16717 if (ext) 16718 *ext++ = '\0'; 16719 host = tmp; 16720 } 16721 16722 if (create_addr(p, host)) { 16723 *cause = AST_CAUSE_UNREGISTERED; 16724 if (option_debug > 2) 16725 ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n"); 16726 sip_destroy(p); 16727 return NULL; 16728 } 16729 if (ast_strlen_zero(p->peername) && ext) 16730 ast_string_field_set(p, peername, ext); 16731 /* Recalculate our side, and recalculate Call ID */ 16732 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16733 p->ourip = __ourip; 16734 build_via(p); 16735 build_callid_pvt(p); 16736 16737 /* We have an extension to call, don't use the full contact here */ 16738 /* This to enable dialing registered peers with extension dialling, 16739 like SIP/peername/extension 16740 SIP/peername will still use the full contact */ 16741 if (ext) { 16742 ast_string_field_set(p, username, ext); 16743 ast_string_field_free(p, fullcontact); 16744 } 16745 #if 0 16746 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 16747 #endif 16748 p->prefcodec = oldformat; /* Format for this call */ 16749 ast_mutex_lock(&p->lock); 16750 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 16751 ast_mutex_unlock(&p->lock); 16752 if (!tmpc) 16753 sip_destroy(p); 16754 ast_update_use_count(); 16755 restart_monitor(); 16756 return tmpc; 16757 }
static int sip_reregister | ( | const void * | data | ) | [static] |
Update registration with SIP Proxy.
Definition at line 7611 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().
07612 { 07613 /* if we are here, we know that we need to reregister. */ 07614 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 07615 07616 /* if we couldn't get a reference to the registry object, punt */ 07617 if (!r) 07618 return 0; 07619 07620 if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 07621 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 07622 /* Since registry's are only added/removed by the the monitor thread, this 07623 may be overkill to reference/dereference at all here */ 07624 if (sipdebug) 07625 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 07626 07627 r->expire = -1; 07628 __sip_do_register(r); 07629 ASTOBJ_UNREF(r, sip_registry_destroy); 07630 return 0; 07631 }
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 4377 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().
04378 { 04379 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 04380 struct ast_frame *f; 04381 04382 if (!p->rtp) { 04383 /* We have no RTP allocated for this channel */ 04384 return &ast_null_frame; 04385 } 04386 04387 switch(ast->fdno) { 04388 case 0: 04389 f = ast_rtp_read(p->rtp); /* RTP Audio */ 04390 break; 04391 case 1: 04392 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 04393 break; 04394 case 2: 04395 f = ast_rtp_read(p->vrtp); /* RTP Video */ 04396 break; 04397 case 3: 04398 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 04399 break; 04400 case 5: 04401 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 04402 break; 04403 default: 04404 f = &ast_null_frame; 04405 } 04406 /* Don't forward RFC2833 if we're not supposed to */ 04407 if (f && (f->frametype == AST_FRAME_DTMF) && 04408 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) 04409 return &ast_null_frame; 04410 04411 /* We already hold the channel lock */ 04412 if (!p->owner || (f && f->frametype != AST_FRAME_VOICE)) 04413 return f; 04414 04415 if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 04416 if (!(f->subclass & p->jointcapability)) { 04417 if (option_debug) { 04418 ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n", 04419 ast_getformatname(f->subclass), p->owner->name); 04420 } 04421 return &ast_null_frame; 04422 } 04423 if (option_debug) 04424 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 04425 p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; 04426 ast_set_read_format(p->owner, p->owner->readformat); 04427 ast_set_write_format(p->owner, p->owner->writeformat); 04428 } 04429 04430 if (f && (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 04431 f = ast_dsp_process(p->owner, p->vad, f); 04432 if (f && f->frametype == AST_FRAME_DTMF) { 04433 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') { 04434 if (option_debug) 04435 ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name); 04436 *faxdetect = 1; 04437 } else if (option_debug) { 04438 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 04439 } 04440 } 04441 } 04442 04443 return f; 04444 }
static void sip_scheddestroy | ( | struct sip_pvt * | p, | |
int | ms | |||
) | [static] |
Schedule destruction of SIP dialog.
Definition at line 2136 of file chan_sip.c.
References __sip_autodestruct(), append_history, ast_sched_add(), AST_SCHED_DEL, ast_test_flag, ast_verbose(), sip_pvt::callid, sip_pvt::flags, sip_pvt::method, sched, sip_debug_test_pvt(), sip_methods, SIP_NO_HISTORY, and sip_pvt::timer_t1.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), and sip_sipredirect().
02137 { 02138 if (ms < 0) { 02139 if (p->timer_t1 == 0) 02140 p->timer_t1 = 500; /* Set timer T1 if not set (RFC 3261) */ 02141 ms = p->timer_t1 * 64; 02142 } 02143 if (sip_debug_test_pvt(p)) 02144 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 02145 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 02146 append_history(p, "SchedDestroy", "%d ms", ms); 02147 02148 AST_SCHED_DEL(sched, p->autokillid); 02149 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 02150 }
static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 18611 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().
18612 { 18613 int ms; 18614 int regspacing; 18615 if (!regobjs) 18616 return; 18617 regspacing = default_expiry * 1000/regobjs; 18618 if (regspacing > 100) 18619 regspacing = 100; 18620 ms = regspacing; 18621 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 18622 ASTOBJ_WRLOCK(iterator); 18623 AST_SCHED_DEL(sched, iterator->expire); 18624 ms += regspacing; 18625 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 18626 ASTOBJ_UNLOCK(iterator); 18627 } while (0) 18628 ); 18629 }
static int sip_send_mwi_to_peer | ( | struct sip_peer * | peer | ) | [static] |
Send message waiting indication to alert peer that they've got voicemail.
Definition at line 16188 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().
16189 { 16190 /* Called with peerl lock, but releases it */ 16191 struct sip_pvt *p; 16192 int newmsgs, oldmsgs; 16193 16194 /* Do we have an IP address? If not, skip this peer */ 16195 if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 16196 return 0; 16197 16198 /* Check for messages */ 16199 ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs); 16200 16201 peer->lastmsgcheck = time(NULL); 16202 16203 /* Return now if it's the same thing we told them last time */ 16204 if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) { 16205 return 0; 16206 } 16207 16208 16209 peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)); 16210 16211 if (peer->mwipvt) { 16212 /* Base message on subscription */ 16213 p = peer->mwipvt; 16214 } else { 16215 /* Build temporary dialog for this message */ 16216 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 16217 return -1; 16218 if (create_addr_from_peer(p, peer)) { 16219 /* Maybe they're not registered, etc. */ 16220 sip_destroy(p); 16221 return 0; 16222 } 16223 /* Recalculate our side, and recalculate Call ID */ 16224 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 16225 p->ourip = __ourip; 16226 build_via(p); 16227 build_callid_pvt(p); 16228 /* Destroy this session after 32 secs */ 16229 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 16230 } 16231 /* Send MWI */ 16232 ast_set_flag(&p->flags[0], SIP_OUTGOING); 16233 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 16234 return 0; 16235 }
static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
char | digit | |||
) | [static] |
Definition at line 3870 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.
03871 { 03872 struct sip_pvt *p = ast->tech_pvt; 03873 int res = 0; 03874 03875 ast_mutex_lock(&p->lock); 03876 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03877 case SIP_DTMF_INBAND: 03878 res = -1; /* Tell Asterisk to generate inband indications */ 03879 break; 03880 case SIP_DTMF_RFC2833: 03881 if (p->rtp) 03882 ast_rtp_senddigit_begin(p->rtp, digit); 03883 break; 03884 default: 03885 break; 03886 } 03887 ast_mutex_unlock(&p->lock); 03888 03889 return res; 03890 }
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 3894 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().
03895 { 03896 struct sip_pvt *p = ast->tech_pvt; 03897 int res = 0; 03898 03899 ast_mutex_lock(&p->lock); 03900 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03901 case SIP_DTMF_INFO: 03902 transmit_info_with_digit(p, digit, duration); 03903 break; 03904 case SIP_DTMF_RFC2833: 03905 if (p->rtp) 03906 ast_rtp_senddigit_end(p->rtp, digit); 03907 break; 03908 case SIP_DTMF_INBAND: 03909 res = -1; /* Tell Asterisk to stop inband indications */ 03910 break; 03911 } 03912 ast_mutex_unlock(&p->lock); 03913 03914 return res; 03915 }
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 2396 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().
02397 { 02398 struct sip_pvt *p = ast->tech_pvt; 02399 int debug = sip_debug_test_pvt(p); 02400 02401 if (debug) 02402 ast_verbose("Sending text %s on %s\n", text, ast->name); 02403 if (!p) 02404 return -1; 02405 if (ast_strlen_zero(text)) 02406 return 0; 02407 if (debug) 02408 ast_verbose("Really sending text %s on %s\n", text, ast->name); 02409 transmit_message_with_text(p, text); 02410 return 0; 02411 }
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 18338 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().
18339 { 18340 struct sip_pvt *p; 18341 int changed = 0; 18342 18343 p = chan->tech_pvt; 18344 if (!p) 18345 return -1; 18346 18347 /* Disable early RTP bridge */ 18348 if (chan->_state != AST_STATE_UP && !global_directrtpsetup) /* We are in early state */ 18349 return 0; 18350 18351 ast_mutex_lock(&p->lock); 18352 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 18353 /* If we're destroyed, don't bother */ 18354 ast_mutex_unlock(&p->lock); 18355 return 0; 18356 } 18357 18358 /* if this peer cannot handle reinvites of the media stream to devices 18359 that are known to be behind a NAT, then stop the process now 18360 */ 18361 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 18362 ast_mutex_unlock(&p->lock); 18363 return 0; 18364 } 18365 18366 if (rtp) { 18367 changed |= ast_rtp_get_peer(rtp, &p->redirip); 18368 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 18369 memset(&p->redirip, 0, sizeof(p->redirip)); 18370 changed = 1; 18371 } 18372 if (vrtp) { 18373 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 18374 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 18375 memset(&p->vredirip, 0, sizeof(p->vredirip)); 18376 changed = 1; 18377 } 18378 if (codecs) { 18379 if ((p->redircodecs != codecs)) { 18380 p->redircodecs = codecs; 18381 changed = 1; 18382 } 18383 if ((p->capability & codecs) != p->capability) { 18384 p->jointcapability &= codecs; 18385 p->capability &= codecs; 18386 changed = 1; 18387 } 18388 } 18389 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 18390 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 18391 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 18392 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 18393 if (option_debug) 18394 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)); 18395 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 18396 if (option_debug > 2) { 18397 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)); 18398 } 18399 transmit_reinvite_with_sdp(p); 18400 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18401 if (option_debug > 2) { 18402 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)); 18403 } 18404 /* We have a pending Invite. Send re-invite when we're done with the invite */ 18405 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18406 } 18407 } 18408 /* Reset lastrtprx timer */ 18409 p->lastrtprx = p->lastrtptx = time(NULL); 18410 ast_mutex_unlock(&p->lock); 18411 return 0; 18412 }
static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
struct ast_udptl * | udptl | |||
) | [static] |
Definition at line 18165 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.
18166 { 18167 struct sip_pvt *p; 18168 18169 p = chan->tech_pvt; 18170 if (!p) 18171 return -1; 18172 ast_mutex_lock(&p->lock); 18173 if (udptl) 18174 ast_udptl_get_peer(udptl, &p->udptlredirip); 18175 else 18176 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 18177 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 18178 if (!p->pendinginvite) { 18179 if (option_debug > 2) { 18180 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); 18181 } 18182 transmit_reinvite_with_t38_sdp(p); 18183 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 18184 if (option_debug > 2) { 18185 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); 18186 } 18187 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 18188 } 18189 } 18190 /* Reset lastrtprx timer */ 18191 p->lastrtprx = p->lastrtptx = time(NULL); 18192 ast_mutex_unlock(&p->lock); 18193 return 0; 18194 }
static int sip_show_channel | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show details of one active dialog.
Definition at line 11232 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.
11233 { 11234 struct sip_pvt *cur; 11235 size_t len; 11236 int found = 0; 11237 11238 if (argc != 4) 11239 return RESULT_SHOWUSAGE; 11240 len = strlen(argv[3]); 11241 ast_mutex_lock(&iflock); 11242 for (cur = iflist; cur; cur = cur->next) { 11243 if (!strncasecmp(cur->callid, argv[3], len)) { 11244 char formatbuf[SIPBUFSIZE/2]; 11245 ast_cli(fd,"\n"); 11246 if (cur->subscribed != NONE) 11247 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 11248 else 11249 ast_cli(fd, " * SIP Call\n"); 11250 ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 11251 ast_cli(fd, " Call-ID: %s\n", cur->callid); 11252 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 11253 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 11254 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 11255 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 11256 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 11257 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 11258 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 11259 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 11260 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 11261 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 11262 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 11263 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)" ); 11264 ast_cli(fd, " Our Tag: %s\n", cur->tag); 11265 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 11266 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 11267 if (!ast_strlen_zero(cur->username)) 11268 ast_cli(fd, " Username: %s\n", cur->username); 11269 if (!ast_strlen_zero(cur->peername)) 11270 ast_cli(fd, " Peername: %s\n", cur->peername); 11271 if (!ast_strlen_zero(cur->uri)) 11272 ast_cli(fd, " Original uri: %s\n", cur->uri); 11273 if (!ast_strlen_zero(cur->cid_num)) 11274 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 11275 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 11276 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 11277 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 11278 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 11279 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 11280 ast_cli(fd, " SIP Options: "); 11281 if (cur->sipoptions) { 11282 int x; 11283 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 11284 if (cur->sipoptions & sip_options[x].id) 11285 ast_cli(fd, "%s ", sip_options[x].text); 11286 } 11287 } else 11288 ast_cli(fd, "(none)\n"); 11289 ast_cli(fd, "\n\n"); 11290 found++; 11291 } 11292 } 11293 ast_mutex_unlock(&iflock); 11294 if (!found) 11295 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11296 return RESULT_SUCCESS; 11297 }
static int sip_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP channels.
Definition at line 11023 of file chan_sip.c.
References __sip_show_channels().
11024 { 11025 return __sip_show_channels(fd, argc, argv, 0); 11026 }
static int sip_show_domains | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command to list local domains.
Definition at line 10535 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.
10536 { 10537 struct domain *d; 10538 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 10539 10540 if (AST_LIST_EMPTY(&domain_list)) { 10541 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 10542 return RESULT_SUCCESS; 10543 } else { 10544 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 10545 AST_LIST_LOCK(&domain_list); 10546 AST_LIST_TRAVERSE(&domain_list, d, list) 10547 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 10548 domain_mode_to_text(d->mode)); 10549 AST_LIST_UNLOCK(&domain_list); 10550 ast_cli(fd, "\n"); 10551 return RESULT_SUCCESS; 10552 } 10553 }
static int sip_show_history | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show history details of one dialog.
Definition at line 11300 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.
11301 { 11302 struct sip_pvt *cur; 11303 size_t len; 11304 int found = 0; 11305 11306 if (argc != 4) 11307 return RESULT_SHOWUSAGE; 11308 if (!recordhistory) 11309 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 11310 len = strlen(argv[3]); 11311 ast_mutex_lock(&iflock); 11312 for (cur = iflist; cur; cur = cur->next) { 11313 if (!strncasecmp(cur->callid, argv[3], len)) { 11314 struct sip_history *hist; 11315 int x = 0; 11316 11317 ast_cli(fd,"\n"); 11318 if (cur->subscribed != NONE) 11319 ast_cli(fd, " * Subscription\n"); 11320 else 11321 ast_cli(fd, " * SIP Call\n"); 11322 if (cur->history) 11323 AST_LIST_TRAVERSE(cur->history, hist, list) 11324 ast_cli(fd, "%d. %s\n", ++x, hist->event); 11325 if (x == 0) 11326 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 11327 found++; 11328 } 11329 } 11330 ast_mutex_unlock(&iflock); 11331 if (!found) 11332 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 11333 return RESULT_SUCCESS; 11334 }
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 9960 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.
09961 { 09962 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 09963 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 09964 char ilimits[40]; 09965 char iused[40]; 09966 int showall = FALSE; 09967 09968 if (argc < 3) 09969 return RESULT_SHOWUSAGE; 09970 09971 if (argc == 4 && !strcmp(argv[3],"all")) 09972 showall = TRUE; 09973 09974 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 09975 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09976 ASTOBJ_RDLOCK(iterator); 09977 if (iterator->call_limit) 09978 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09979 else 09980 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09981 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 09982 if (showall || iterator->call_limit) 09983 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09984 ASTOBJ_UNLOCK(iterator); 09985 } while (0) ); 09986 09987 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 09988 09989 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09990 ASTOBJ_RDLOCK(iterator); 09991 if (iterator->call_limit) 09992 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09993 else 09994 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09995 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 09996 if (showall || iterator->call_limit) 09997 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09998 ASTOBJ_UNLOCK(iterator); 09999 } while (0) ); 10000 10001 return RESULT_SUCCESS; 10002 #undef FORMAT 10003 #undef FORMAT2 10004 }
static int sip_show_objects | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 10281 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
10282 { 10283 char tmp[256]; 10284 if (argc != 3) 10285 return RESULT_SHOWUSAGE; 10286 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 10287 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 10288 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 10289 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 10290 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 10291 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 10292 return RESULT_SUCCESS; 10293 }
static int sip_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 10587 of file chan_sip.c.
References _sip_show_peer().
10588 { 10589 return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); 10590 }
static int sip_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Show Peers command.
Definition at line 10137 of file chan_sip.c.
References _sip_show_peers().
10138 { 10139 return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); 10140 }
static int sip_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 10860 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.
10861 { 10862 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 10863 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 10864 char host[80]; 10865 char tmpdat[256]; 10866 struct tm tm; 10867 10868 10869 if (argc != 3) 10870 return RESULT_SHOWUSAGE; 10871 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 10872 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 10873 ASTOBJ_RDLOCK(iterator); 10874 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 10875 if (iterator->regtime) { 10876 ast_localtime(&iterator->regtime, &tm, NULL); 10877 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 10878 } else { 10879 tmpdat[0] = 0; 10880 } 10881 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 10882 ASTOBJ_UNLOCK(iterator); 10883 } while(0)); 10884 return RESULT_SUCCESS; 10885 #undef FORMAT 10886 #undef FORMAT2 10887 }
static int sip_show_settings | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
List global settings for the SIP channel.
Definition at line 10890 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().
10891 { 10892 int realtimepeers; 10893 int realtimeusers; 10894 char codec_buf[SIPBUFSIZE]; 10895 10896 realtimepeers = ast_check_realtime("sippeers"); 10897 realtimeusers = ast_check_realtime("sipusers"); 10898 10899 if (argc != 3) 10900 return RESULT_SHOWUSAGE; 10901 ast_cli(fd, "\n\nGlobal Settings:\n"); 10902 ast_cli(fd, "----------------\n"); 10903 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 10904 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 10905 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 10906 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 10907 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 10908 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10909 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10910 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 10911 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 10912 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 10913 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 10914 ast_cli(fd, " Our auth realm %s\n", global_realm); 10915 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 10916 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 10917 ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No"); 10918 ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No"); 10919 ast_cli(fd, " User Agent: %s\n", global_useragent); 10920 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 10921 ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 10922 ast_cli(fd, " Caller ID: %s\n", default_callerid); 10923 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 10924 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 10925 ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 10926 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 10927 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 10928 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 10929 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 10930 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10931 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 10932 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 10933 #endif 10934 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 10935 if (!realtimepeers && !realtimeusers) 10936 ast_cli(fd, " SIP realtime: Disabled\n" ); 10937 else 10938 ast_cli(fd, " SIP realtime: Enabled\n" ); 10939 10940 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 10941 ast_cli(fd, "---------------------------\n"); 10942 ast_cli(fd, " Codecs: "); 10943 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 10944 ast_cli(fd, "%s\n", codec_buf); 10945 ast_cli(fd, " Codec Order: "); 10946 print_codec_to_cli(fd, &default_prefs); 10947 ast_cli(fd, "\n"); 10948 ast_cli(fd, " T1 minimum: %d\n", global_t1min); 10949 ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No"); 10950 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 10951 ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 10952 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 10953 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 10954 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 10955 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 10956 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 10957 ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); 10958 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 10959 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 10960 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 10961 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 10962 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 10963 ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No"); 10964 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 10965 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate); 10966 ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No"); 10967 ast_cli(fd, "\nDefault Settings:\n"); 10968 ast_cli(fd, "-----------------\n"); 10969 ast_cli(fd, " Context: %s\n", default_context); 10970 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 10971 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 10972 ast_cli(fd, " Qualify: %d\n", default_qualify); 10973 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 10974 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" ); 10975 ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)")); 10976 ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); 10977 ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); 10978 ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); 10979 10980 10981 if (realtimepeers || realtimeusers) { 10982 ast_cli(fd, "\nRealtime SIP Settings:\n"); 10983 ast_cli(fd, "----------------------\n"); 10984 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 10985 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 10986 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 10987 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 10988 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 10989 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 10990 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 10991 } 10992 ast_cli(fd, "\n----\n"); 10993 return RESULT_SUCCESS; 10994 }
static int sip_show_subscriptions | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show active SIP subscriptions.
Definition at line 11029 of file chan_sip.c.
References __sip_show_channels().
11030 { 11031 return __sip_show_channels(fd, argc, argv, 1); 11032 }
static int sip_show_user | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one user in detail.
Definition at line 10805 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.
10806 { 10807 char cbuf[256]; 10808 struct sip_user *user; 10809 struct ast_variable *v; 10810 int load_realtime; 10811 10812 if (argc < 4) 10813 return RESULT_SHOWUSAGE; 10814 10815 /* Load from realtime storage? */ 10816 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10817 10818 user = find_user(argv[3], load_realtime); 10819 if (user) { 10820 ast_cli(fd,"\n\n"); 10821 ast_cli(fd, " * Name : %s\n", user->name); 10822 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 10823 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 10824 ast_cli(fd, " Context : %s\n", user->context); 10825 ast_cli(fd, " Language : %s\n", user->language); 10826 if (!ast_strlen_zero(user->accountcode)) 10827 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 10828 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 10829 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 10830 ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 10831 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 10832 ast_cli(fd, " Call limit : %d\n", user->call_limit); 10833 ast_cli(fd, " Callgroup : "); 10834 print_group(fd, user->callgroup, 0); 10835 ast_cli(fd, " Pickupgroup : "); 10836 print_group(fd, user->pickupgroup, 0); 10837 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 10838 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 10839 ast_cli(fd, " Codec Order : ("); 10840 print_codec_to_cli(fd, &user->prefs); 10841 ast_cli(fd, ")\n"); 10842 10843 ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No"); 10844 if (user->chanvars) { 10845 ast_cli(fd, " Variables :\n"); 10846 for (v = user->chanvars ; v ; v = v->next) 10847 ast_cli(fd, " %s = %s\n", v->name, v->value); 10848 } 10849 ast_cli(fd,"\n"); 10850 ASTOBJ_UNREF(user,sip_destroy_user); 10851 } else { 10852 ast_cli(fd,"User %s not found.\n", argv[3]); 10853 ast_cli(fd,"\n"); 10854 } 10855 10856 return RESULT_SUCCESS; 10857 }
static int sip_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 10060 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.
10061 { 10062 regex_t regexbuf; 10063 int havepattern = FALSE; 10064 10065 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 10066 10067 switch (argc) { 10068 case 5: 10069 if (!strcasecmp(argv[3], "like")) { 10070 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 10071 return RESULT_SHOWUSAGE; 10072 havepattern = TRUE; 10073 } else 10074 return RESULT_SHOWUSAGE; 10075 case 3: 10076 break; 10077 default: 10078 return RESULT_SHOWUSAGE; 10079 } 10080 10081 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 10082 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 10083 ASTOBJ_RDLOCK(iterator); 10084 10085 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 10086 ASTOBJ_UNLOCK(iterator); 10087 continue; 10088 } 10089 10090 ast_cli(fd, FORMAT, iterator->name, 10091 iterator->secret, 10092 iterator->accountcode, 10093 iterator->context, 10094 iterator->ha ? "Yes" : "No", 10095 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 10096 ASTOBJ_UNLOCK(iterator); 10097 } while (0) 10098 ); 10099 10100 if (havepattern) 10101 regfree(®exbuf); 10102 10103 return RESULT_SUCCESS; 10104 #undef FORMAT 10105 }
static int sip_sipredirect | ( | struct sip_pvt * | p, | |
const char * | dest | |||
) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 18525 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().
18526 { 18527 char *cdest; 18528 char *extension, *host, *port; 18529 char tmp[80]; 18530 18531 cdest = ast_strdupa(dest); 18532 18533 extension = strsep(&cdest, "@"); 18534 host = strsep(&cdest, ":"); 18535 port = strsep(&cdest, ":"); 18536 if (ast_strlen_zero(extension)) { 18537 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 18538 return 0; 18539 } 18540 18541 /* we'll issue the redirect message here */ 18542 if (!host) { 18543 char *localtmp; 18544 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 18545 if (ast_strlen_zero(tmp)) { 18546 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 18547 return 0; 18548 } 18549 if ((localtmp = strcasestr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 18550 char lhost[80], lport[80]; 18551 memset(lhost, 0, sizeof(lhost)); 18552 memset(lport, 0, sizeof(lport)); 18553 localtmp++; 18554 /* This is okey because lhost and lport are as big as tmp */ 18555 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 18556 if (ast_strlen_zero(lhost)) { 18557 ast_log(LOG_ERROR, "Can't find the host address\n"); 18558 return 0; 18559 } 18560 host = ast_strdupa(lhost); 18561 if (!ast_strlen_zero(lport)) { 18562 port = ast_strdupa(lport); 18563 } 18564 } 18565 } 18566 18567 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 18568 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 18569 18570 sip_scheddestroy(p, SIP_TRANS_TIMEOUT); /* Make sure we stop send this reply. */ 18571 sip_alreadygone(p); 18572 return 0; 18573 }
static int sip_transfer | ( | struct ast_channel * | ast, | |
const char * | dest | |||
) | [static] |
Transfer SIP call.
Definition at line 3918 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().
03919 { 03920 struct sip_pvt *p = ast->tech_pvt; 03921 int res; 03922 03923 if (dest == NULL) /* functions below do not take a NULL */ 03924 dest = ""; 03925 ast_mutex_lock(&p->lock); 03926 if (ast->_state == AST_STATE_RING) 03927 res = sip_sipredirect(p, dest); 03928 else 03929 res = transmit_refer(p, dest); 03930 ast_mutex_unlock(&p->lock); 03931 return res; 03932 }
static int sip_uri_cmp | ( | const char * | input1, | |
const char * | input2 | |||
) | [static] |
Definition at line 14125 of file chan_sip.c.
References ast_strdupa, S_OR, sip_uri_headers_cmp(), and sip_uri_params_cmp().
Referenced by handle_request_invite().
14126 { 14127 char *uri1 = ast_strdupa(input1); 14128 char *uri2 = ast_strdupa(input2); 14129 char *host1; 14130 char *host2; 14131 char *params1; 14132 char *params2; 14133 char *headers1; 14134 char *headers2; 14135 14136 /* Strip off "sip:" from the URI. We know this is present 14137 * because it was checked back in parse_request() 14138 */ 14139 strsep(&uri1, ":"); 14140 strsep(&uri2, ":"); 14141 14142 if ((host1 = strchr(uri1, '@'))) { 14143 *host1++ = '\0'; 14144 } 14145 if ((host2 = strchr(uri2, '@'))) { 14146 *host2++ = '\0'; 14147 } 14148 14149 /* Check for mismatched username and passwords. This is the 14150 * only case-sensitive comparison of a SIP URI 14151 */ 14152 if ((host1 && !host2) || 14153 (host2 && !host1) || 14154 (host1 && host2 && strcmp(uri1, uri2))) { 14155 return 1; 14156 } 14157 14158 if (!host1) 14159 host1 = uri1; 14160 if (!host2) 14161 host2 = uri2; 14162 14163 /* Strip off the parameters and headers so we can compare 14164 * host and port 14165 */ 14166 14167 if ((params1 = strchr(host1, ';'))) { 14168 *params1++ = '\0'; 14169 } 14170 if ((params2 = strchr(host2, ';'))) { 14171 *params2++ = '\0'; 14172 } 14173 14174 /* Headers come after parameters, but there may be headers without 14175 * parameters, thus the S_OR 14176 */ 14177 if ((headers1 = strchr(S_OR(params1, host1), '?'))) { 14178 *headers1++ = '\0'; 14179 } 14180 if ((headers2 = strchr(S_OR(params2, host2), '?'))) { 14181 *headers2++ = '\0'; 14182 } 14183 14184 /* Now the host/port are properly isolated. We can get by with a string comparison 14185 * because the SIP URI checking rules have some interesting exceptions that make 14186 * this possible. I will note 2 in particular 14187 * 1. hostnames which resolve to the same IP address as well as a hostname and its 14188 * IP address are not considered a match with SIP URI's. 14189 * 2. If one URI specifies a port and the other does not, then the URIs do not match. 14190 * This includes if one URI explicitly contains port 5060 and the other implies it 14191 * by not having a port specified. 14192 */ 14193 14194 if (strcasecmp(host1, host2)) { 14195 return 1; 14196 } 14197 14198 /* Headers have easier rules to follow, so do those first */ 14199 if (sip_uri_headers_cmp(headers1, headers2)) { 14200 return 1; 14201 } 14202 14203 /* And now the parameters. Ugh */ 14204 return sip_uri_params_cmp(params1, params2); 14205 }
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 14091 of file chan_sip.c.
References ast_strdupa, and ast_strlen_zero().
Referenced by sip_uri_cmp().
14092 { 14093 char *headers1 = ast_strdupa(input1); 14094 char *headers2 = ast_strdupa(input2); 14095 int zerolength1 = ast_strlen_zero(headers1); 14096 int zerolength2 = ast_strlen_zero(headers2); 14097 int different = 0; 14098 char *header1; 14099 14100 if ((zerolength1 && !zerolength2) || 14101 (zerolength2 && !zerolength1)) 14102 return 1; 14103 14104 if (zerolength1 && zerolength2) 14105 return 0; 14106 14107 /* At this point, we can definitively state that both inputs are 14108 * not zero-length. First, one more optimization. If the length 14109 * of the headers is not equal, then we definitely have no match 14110 */ 14111 if (strlen(headers1) != strlen(headers2)) { 14112 return 1; 14113 } 14114 14115 for (header1 = strsep(&headers1, "&"); header1; header1 = strsep(&headers1, "&")) { 14116 if (!strcasestr(headers2, header1)) { 14117 different = 1; 14118 break; 14119 } 14120 } 14121 14122 return different; 14123 }
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 13964 of file chan_sip.c.
References ast_strdupa, and ast_strlen_zero().
Referenced by sip_uri_cmp().
13965 { 13966 char *params1 = ast_strdupa(input1); 13967 char *params2 = ast_strdupa(input2); 13968 char *pos1; 13969 char *pos2; 13970 int maddrmatch = 0; 13971 int ttlmatch = 0; 13972 int usermatch = 0; 13973 int methodmatch = 0; 13974 13975 /*Quick optimization. If both params are zero-length, then 13976 * they match 13977 */ 13978 if (ast_strlen_zero(params1) && ast_strlen_zero(params2)) { 13979 return 0; 13980 } 13981 13982 pos1 = params1; 13983 while (!ast_strlen_zero(pos1)) { 13984 char *name1 = pos1; 13985 char *value1 = strchr(pos1, '='); 13986 char *semicolon1 = strchr(pos1, ';'); 13987 int matched = 0; 13988 if (semicolon1) { 13989 *semicolon1++ = '\0'; 13990 } 13991 if (!value1) { 13992 goto fail; 13993 } 13994 *value1++ = '\0'; 13995 /* Checkpoint reached. We have the name and value parsed for param1 13996 * We have to duplicate params2 each time through the second loop 13997 * or else we can't search and replace the semicolons with \0 each 13998 * time 13999 */ 14000 pos2 = ast_strdupa(params2); 14001 while (!ast_strlen_zero(pos2)) { 14002 char *name2 = pos2; 14003 char *value2 = strchr(pos2, '='); 14004 char *semicolon2 = strchr(pos2, ';'); 14005 if (semicolon2) { 14006 *semicolon2++ = '\0'; 14007 } 14008 if (!value2) { 14009 goto fail; 14010 } 14011 *value2++ = '\0'; 14012 if (!strcasecmp(name1, name2)) { 14013 if (strcasecmp(value1, value2)) { 14014 goto fail; 14015 } else { 14016 matched = 1; 14017 break; 14018 } 14019 } 14020 pos2 = semicolon2; 14021 } 14022 /* Need to see if the parameter we're looking at is one of the 'must-match' parameters */ 14023 if (!strcasecmp(name1, "maddr")) { 14024 if (matched) { 14025 maddrmatch = 1; 14026 } else { 14027 goto fail; 14028 } 14029 } else if (!strcasecmp(name1, "ttl")) { 14030 if (matched) { 14031 ttlmatch = 1; 14032 } else { 14033 goto fail; 14034 } 14035 } else if (!strcasecmp(name1, "user")) { 14036 if (matched) { 14037 usermatch = 1; 14038 } else { 14039 goto fail; 14040 } 14041 } else if (!strcasecmp(name1, "method")) { 14042 if (matched) { 14043 methodmatch = 1; 14044 } else { 14045 goto fail; 14046 } 14047 } 14048 pos1 = semicolon1; 14049 } 14050 14051 /* We've made it out of that horrible O(m*n) construct and there are no 14052 * failures yet. We're not done yet, though, because params2 could have 14053 * an maddr, ttl, user, or method header and params1 did not. 14054 */ 14055 pos2 = params2; 14056 while (!ast_strlen_zero(pos2)) { 14057 char *name2 = pos2; 14058 char *value2 = strchr(pos2, '='); 14059 char *semicolon2 = strchr(pos2, ';'); 14060 if (semicolon2) { 14061 *semicolon2++ = '\0'; 14062 } 14063 if (!value2) { 14064 goto fail; 14065 } 14066 *value2++ = '\0'; 14067 if ((!strcasecmp(name2, "maddr") && !maddrmatch) || 14068 (!strcasecmp(name2, "ttl") && !ttlmatch) || 14069 (!strcasecmp(name2, "user") && !usermatch) || 14070 (!strcasecmp(name2, "method") && !methodmatch)) { 14071 goto fail; 14072 } 14073 } 14074 return 0; 14075 14076 fail: 14077 return 1; 14078 }
static int sip_write | ( | struct ast_channel * | ast, | |
struct ast_frame * | frame | |||
) | [static] |
Send frame to media channel (rtp).
Definition at line 3743 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.
03744 { 03745 struct sip_pvt *p = ast->tech_pvt; 03746 int res = 0; 03747 03748 switch (frame->frametype) { 03749 case AST_FRAME_VOICE: 03750 if (!(frame->subclass & ast->nativeformats)) { 03751 char s1[512], s2[512], s3[512]; 03752 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n", 03753 frame->subclass, 03754 ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK), 03755 ast->nativeformats & AST_FORMAT_AUDIO_MASK, 03756 ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat), 03757 ast->readformat, 03758 ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat), 03759 ast->writeformat); 03760 return 0; 03761 } 03762 if (p) { 03763 ast_mutex_lock(&p->lock); 03764 if (p->rtp) { 03765 /* If channel is not up, activate early media session */ 03766 if ((ast->_state != AST_STATE_UP) && 03767 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03768 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03769 ast_rtp_new_source(p->rtp); 03770 p->invitestate = INV_EARLY_MEDIA; 03771 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03772 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03773 } 03774 p->lastrtptx = time(NULL); 03775 res = ast_rtp_write(p->rtp, frame); 03776 } 03777 ast_mutex_unlock(&p->lock); 03778 } 03779 break; 03780 case AST_FRAME_VIDEO: 03781 if (p) { 03782 ast_mutex_lock(&p->lock); 03783 if (p->vrtp) { 03784 /* Activate video early media */ 03785 if ((ast->_state != AST_STATE_UP) && 03786 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03787 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03788 p->invitestate = INV_EARLY_MEDIA; 03789 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03790 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03791 } 03792 p->lastrtptx = time(NULL); 03793 res = ast_rtp_write(p->vrtp, frame); 03794 } 03795 ast_mutex_unlock(&p->lock); 03796 } 03797 break; 03798 case AST_FRAME_IMAGE: 03799 return 0; 03800 break; 03801 case AST_FRAME_MODEM: 03802 if (p) { 03803 ast_mutex_lock(&p->lock); 03804 /* UDPTL requires two-way communication, so early media is not needed here. 03805 we simply forget the frames if we get modem frames before the bridge is up. 03806 Fax will re-transmit. 03807 */ 03808 if (p->udptl && ast->_state == AST_STATE_UP) 03809 res = ast_udptl_write(p->udptl, frame); 03810 ast_mutex_unlock(&p->lock); 03811 } 03812 break; 03813 default: 03814 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 03815 return 0; 03816 } 03817 03818 return res; 03819 }
static int sipsock_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | ignore | |||
) | [static] |
Read data from SIP socket.
Definition at line 16068 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().
16069 { 16070 struct sip_request req; 16071 struct sockaddr_in sin = { 0, }; 16072 struct sip_pvt *p; 16073 int res; 16074 socklen_t len = sizeof(sin); 16075 int nounlock = 0; 16076 int recount = 0; 16077 int lockretry; 16078 16079 memset(&req, 0, sizeof(req)); 16080 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 16081 if (res < 0) { 16082 #if !defined(__FreeBSD__) 16083 if (errno == EAGAIN) 16084 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 16085 else 16086 #endif 16087 if (errno != ECONNREFUSED) 16088 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 16089 return 1; 16090 } 16091 if (option_debug && res == sizeof(req.data) - 1) 16092 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 16093 16094 req.data[res] = '\0'; 16095 req.len = res; 16096 if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */ 16097 ast_set_flag(&req, SIP_PKT_DEBUG); 16098 if (pedanticsipchecking) 16099 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 16100 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 16101 ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data); 16102 16103 if(parse_request(&req) == -1) /* Bad packet, can't parse */ 16104 return 1; 16105 16106 req.method = find_sip_method(req.rlPart1); 16107 16108 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 16109 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 16110 16111 if (req.headers < 2) /* Must have at least two headers */ 16112 return 1; 16113 16114 /* Process request, with netlock held, and with usual deadlock avoidance */ 16115 for (lockretry = 10; lockretry > 0; lockretry--) { 16116 ast_mutex_lock(&netlock); 16117 16118 /* Find the active SIP dialog or create a new one */ 16119 p = find_call(&req, &sin, req.method); /* returns p locked */ 16120 if (p == NULL) { 16121 if (option_debug) 16122 ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len); 16123 ast_mutex_unlock(&netlock); 16124 return 1; 16125 } 16126 /* Go ahead and lock the owner if it has one -- we may need it */ 16127 /* because this is deadlock-prone, we need to try and unlock if failed */ 16128 if (!p->owner || !ast_channel_trylock(p->owner)) 16129 break; /* locking succeeded */ 16130 if (lockretry != 1) { 16131 ast_mutex_unlock(&p->lock); 16132 ast_mutex_unlock(&netlock); 16133 /* Sleep for a very short amount of time */ 16134 usleep(1); 16135 } 16136 } 16137 p->recv = sin; 16138 16139 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */ 16140 append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2); 16141 16142 if (!lockretry) { 16143 if (!queue_request(p, &req)) { 16144 /* the request has been queued for later handling */ 16145 ast_mutex_unlock(&p->lock); 16146 ast_mutex_unlock(&netlock); 16147 return 1; 16148 } 16149 16150 /* This is unsafe, since p->owner is not locked. */ 16151 if (p->owner) 16152 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 ??? - ")); 16153 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 16154 if (req.method != SIP_ACK) 16155 transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */ 16156 /* XXX We could add retry-after to make sure they come back */ 16157 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 16158 ast_mutex_unlock(&p->lock); 16159 ast_mutex_unlock(&netlock); 16160 return 1; 16161 } 16162 16163 /* if there are queued requests on this sip_pvt, process them first, so that everything is 16164 handled in order 16165 */ 16166 if (!AST_LIST_EMPTY(&p->request_queue)) { 16167 AST_SCHED_DEL(sched, p->request_queue_sched_id); 16168 process_request_queue(p, &recount, &nounlock); 16169 } 16170 16171 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 16172 /* Request failed */ 16173 if (option_debug) 16174 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 16175 } 16176 16177 if (p->owner && !nounlock) 16178 ast_channel_unlock(p->owner); 16179 ast_mutex_unlock(&p->lock); 16180 ast_mutex_unlock(&netlock); 16181 if (recount) 16182 ast_update_use_count(); 16183 16184 return 1; 16185 }
static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 12889 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().
12890 { 12891 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12892 if (p->rtp) 12893 ast_rtp_stop(p->rtp); 12894 if (p->vrtp) 12895 ast_rtp_stop(p->vrtp); 12896 if (p->udptl) 12897 ast_udptl_stop(p->udptl); 12898 }
static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 10997 of file chan_sip.c.
References subscription_types, and type.
Referenced by sip_show_channel().
10998 { 10999 int i; 11000 11001 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 11002 if (subscription_types[i].type == subtype) { 11003 return subscription_types[i].text; 11004 } 11005 } 11006 return subscription_types[0].text; 11007 }
static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 6417 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().
06418 { 06419 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 06420 06421 if (maxrate & T38FAX_RATE_14400) { 06422 if (option_debug > 1) 06423 ast_log(LOG_DEBUG, "T38MaxBitRate 14400 found\n"); 06424 return 14400; 06425 } else if (maxrate & T38FAX_RATE_12000) { 06426 if (option_debug > 1) 06427 ast_log(LOG_DEBUG, "T38MaxBitRate 12000 found\n"); 06428 return 12000; 06429 } else if (maxrate & T38FAX_RATE_9600) { 06430 if (option_debug > 1) 06431 ast_log(LOG_DEBUG, "T38MaxBitRate 9600 found\n"); 06432 return 9600; 06433 } else if (maxrate & T38FAX_RATE_7200) { 06434 if (option_debug > 1) 06435 ast_log(LOG_DEBUG, "T38MaxBitRate 7200 found\n"); 06436 return 7200; 06437 } else if (maxrate & T38FAX_RATE_4800) { 06438 if (option_debug > 1) 06439 ast_log(LOG_DEBUG, "T38MaxBitRate 4800 found\n"); 06440 return 4800; 06441 } else if (maxrate & T38FAX_RATE_2400) { 06442 if (option_debug > 1) 06443 ast_log(LOG_DEBUG, "T38MaxBitRate 2400 found\n"); 06444 return 2400; 06445 } else { 06446 if (option_debug > 1) 06447 ast_log(LOG_DEBUG, "Strange, T38MaxBitRate NOT found in peers T38 SDP.\n"); 06448 return 0; 06449 } 06450 }
static struct sip_peer * temp_peer | ( | const char * | name | ) | [static] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 17238 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().
17239 { 17240 struct sip_peer *peer; 17241 17242 if (!(peer = ast_calloc(1, sizeof(*peer)))) 17243 return NULL; 17244 17245 apeerobjs++; 17246 ASTOBJ_INIT(peer); 17247 set_peer_defaults(peer); 17248 17249 ast_copy_string(peer->name, name, sizeof(peer->name)); 17250 17251 ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT); 17252 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 17253 peer->prefs = default_prefs; 17254 reg_source_db(peer); 17255 17256 return peer; 17257 }
static void temp_pvt_cleanup | ( | void * | ) | [static] |
Definition at line 6192 of file chan_sip.c.
References ast_string_field_free_memory, and free.
06193 { 06194 struct sip_pvt *p = data; 06195 06196 ast_string_field_free_memory(p); 06197 06198 free(data); 06199 }
static void temp_pvt_init | ( | void | ) | [static] |
static char * transfermode2str | ( | enum transfermodes | mode | ) | const [static] |
Convert transfer mode to text string.
Definition at line 10007 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().
10008 { 10009 if (mode == TRANSFER_OPENFORALL) 10010 return "open"; 10011 else if (mode == TRANSFER_CLOSED) 10012 return "closed"; 10013 return "strict"; 10014 }
static void transmit_fake_auth_response | ( | struct sip_pvt * | p, | |
struct sip_request * | req, | |||
int | reliable | |||
) | [static] |
Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers.
Definition at line 8814 of file chan_sip.c.
References ast_random(), ast_string_field_build, sip_pvt::randdata, and transmit_response_with_auth().
Referenced by handle_request_invite(), handle_request_subscribe(), and register_verify().
08815 { 08816 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08817 transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0); 08818 }
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 7981 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
07982 { 07983 struct sip_request req; 07984 07985 reqprep(&req, p, SIP_INFO, 0, 1); 07986 add_digit(&req, digit, duration); 07987 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07988 }
static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 7991 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
07992 { 07993 struct sip_request req; 07994 07995 reqprep(&req, p, SIP_INFO, 0, 1); 07996 add_vidupdate(&req); 07997 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07998 }
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 7227 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().
07228 { 07229 struct sip_request req; 07230 07231 req.method = sipmethod; 07232 if (init) { /* Seems like init always is 2 */ 07233 /* Bump branch even on initial requests */ 07234 p->branch ^= ast_random(); 07235 p->invite_branch = p->branch; 07236 build_via(p); 07237 if (init > 1) 07238 initreqprep(&req, p, sipmethod); 07239 else 07240 reqprep(&req, p, sipmethod, 0, 1); 07241 } else 07242 reqprep(&req, p, sipmethod, 0, 1); 07243 07244 if (p->options && p->options->auth) 07245 add_header(&req, p->options->authheader, p->options->auth); 07246 append_date(&req); 07247 if (sipmethod == SIP_REFER) { /* Call transfer */ 07248 if (p->refer) { 07249 char buf[SIPBUFSIZE]; 07250 if (!ast_strlen_zero(p->refer->refer_to)) 07251 add_header(&req, "Refer-To", p->refer->refer_to); 07252 if (!ast_strlen_zero(p->refer->referred_by)) { 07253 snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 07254 add_header(&req, "Referred-By", buf); 07255 } 07256 } 07257 } 07258 /* This new INVITE is part of an attended transfer. Make sure that the 07259 other end knows and replace the current call with this new call */ 07260 if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) { 07261 add_header(&req, "Replaces", p->options->replaces); 07262 add_header(&req, "Require", "replaces"); 07263 } 07264 07265 add_header(&req, "Allow", ALLOWED_METHODS); 07266 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07267 if (p->options && p->options->addsipheaders && p->owner) { 07268 struct ast_channel *chan = p->owner; /* The owner channel */ 07269 struct varshead *headp; 07270 07271 ast_channel_lock(chan); 07272 07273 headp = &chan->varshead; 07274 07275 if (!headp) 07276 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 07277 else { 07278 const struct ast_var_t *current; 07279 AST_LIST_TRAVERSE(headp, current, entries) { 07280 /* SIPADDHEADER: Add SIP header to outgoing call */ 07281 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 07282 char *content, *end; 07283 const char *header = ast_var_value(current); 07284 char *headdup = ast_strdupa(header); 07285 07286 /* Strip of the starting " (if it's there) */ 07287 if (*headdup == '"') 07288 headdup++; 07289 if ((content = strchr(headdup, ':'))) { 07290 *content++ = '\0'; 07291 content = ast_skip_blanks(content); /* Skip white space */ 07292 /* Strip the ending " (if it's there) */ 07293 end = content + strlen(content) -1; 07294 if (*end == '"') 07295 *end = '\0'; 07296 07297 add_header(&req, headdup, content); 07298 if (sipdebug) 07299 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 07300 } 07301 } 07302 } 07303 } 07304 07305 ast_channel_unlock(chan); 07306 } 07307 if (sdp) { 07308 if (p->udptl && (p->t38.state == T38_LOCAL_DIRECT || p->t38.state == T38_LOCAL_REINVITE)) { 07309 ast_udptl_offered_from_local(p->udptl, 1); 07310 if (option_debug) 07311 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 07312 add_t38_sdp(&req, p); 07313 } else if (p->rtp) 07314 add_sdp(&req, p); 07315 } else { 07316 add_header_contentLength(&req, 0); 07317 } 07318 07319 if (!p->initreq.headers || init > 2) 07320 initialize_initreq(p, &req); 07321 p->lastinvite = p->ocseq; 07322 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 07323 }
static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
const char * | text | |||
) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 7890 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().
07891 { 07892 struct sip_request req; 07893 07894 reqprep(&req, p, SIP_MESSAGE, 0, 1); 07895 add_text(&req, text); 07896 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07897 }
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 7514 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().
07515 { 07516 struct sip_request req; 07517 char tmp[500]; 07518 char *t = tmp; 07519 size_t maxbytes = sizeof(tmp); 07520 07521 initreqprep(&req, p, SIP_NOTIFY); 07522 add_header(&req, "Event", "message-summary"); 07523 add_header(&req, "Content-Type", default_notifymime); 07524 07525 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 07526 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 07527 S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 07528 /* Cisco has a bug in the SIP stack where it can't accept the 07529 (0/0) notification. This can temporarily be disabled in 07530 sip.conf with the "buggymwi" option */ 07531 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)")); 07532 07533 if (p->subscribed) { 07534 if (p->expiry) 07535 add_header(&req, "Subscription-State", "active"); 07536 else /* Expired */ 07537 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07538 } 07539 07540 if (t > tmp + sizeof(tmp)) 07541 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07542 07543 add_header_contentLength(&req, strlen(tmp)); 07544 add_line(&req, tmp); 07545 07546 if (!p->initreq.headers) 07547 initialize_initreq(p, &req); 07548 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07549 }
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 7560 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().
07561 { 07562 struct sip_request req; 07563 char tmp[SIPBUFSIZE/2]; 07564 07565 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07566 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 07567 add_header(&req, "Event", tmp); 07568 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 07569 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 07570 add_header(&req, "Allow", ALLOWED_METHODS); 07571 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07572 07573 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 07574 add_header_contentLength(&req, strlen(tmp)); 07575 add_line(&req, tmp); 07576 07577 if (!p->initreq.headers) 07578 initialize_initreq(p, &req); 07579 07580 p->lastnoninvite = p->ocseq; 07581 07582 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07583 }
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 7911 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().
07912 { 07913 struct sip_request req = { 07914 .headers = 0, 07915 }; 07916 char from[256]; 07917 const char *of; 07918 char *c; 07919 char referto[256]; 07920 char *ttag, *ftag; 07921 char *theirtag = ast_strdupa(p->theirtag); 07922 07923 if (option_debug || sipdebug) 07924 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 07925 07926 /* Are we transfering an inbound or outbound call ? */ 07927 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07928 of = get_header(&p->initreq, "To"); 07929 ttag = theirtag; 07930 ftag = p->tag; 07931 } else { 07932 of = get_header(&p->initreq, "From"); 07933 ftag = theirtag; 07934 ttag = p->tag; 07935 } 07936 07937 ast_copy_string(from, of, sizeof(from)); 07938 of = get_in_brackets(from); 07939 ast_string_field_set(p, from, of); 07940 if (strncasecmp(of, "sip:", 4)) 07941 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 07942 else 07943 of += 4; 07944 /* Get just the username part */ 07945 if ((c = strchr(dest, '@'))) 07946 c = NULL; 07947 else if ((c = strchr(of, '@'))) 07948 *c++ = '\0'; 07949 if (c) 07950 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 07951 else 07952 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 07953 07954 /* save in case we get 407 challenge */ 07955 sip_refer_allocate(p); 07956 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 07957 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 07958 p->refer->status = REFER_SENT; /* Set refer status */ 07959 07960 reqprep(&req, p, SIP_REFER, 0, 1); 07961 07962 add_header(&req, "Refer-To", referto); 07963 add_header(&req, "Allow", ALLOWED_METHODS); 07964 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07965 if (!ast_strlen_zero(p->our_contact)) 07966 add_header(&req, "Referred-By", p->our_contact); 07967 07968 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07969 /* We should propably wait for a NOTIFY here until we ack the transfer */ 07970 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 07971 07972 /*! \todo In theory, we should hang around and wait for a reply, before 07973 returning to the dial plan here. Don't know really how that would 07974 affect the transfer() app or the pbx, but, well, to make this 07975 useful we should have a STATUS code on transfer(). 07976 */ 07977 }
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 7687 of file chan_sip.c.
References __ourip, add_header(), add_header_contentLength(), append_history, ast_log(), ast_random(), ast_sched_add(), AST_SCHED_DEL, ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, sip_pvt::authname, sip_registry::authuser, bindaddr, sip_pvt::branch, build_callid_registry(), build_contact(), build_reply_digest(), build_via(), sip_registry::call, sip_pvt::callid, sip_registry::callid, sip_registry::callid_valid, sip_registry::contact, create_addr(), DEFAULT_MAX_FORWARDS, sip_registry::domain, exten, sip_pvt::flags, sip_pvt::fromdomain, sip_pvt::fromuser, sip_request::headers, sip_registry::hostname, init_req(), initialize_initreq(), sip_pvt::initreq, sip_request::lines, LOG_DEBUG, LOG_NOTICE, make_our_tag(), sip_registry::md5secret, sip_pvt::nonce, sip_registry::nonce, sip_pvt::noncecount, sip_registry::noncecount, sip_pvt::ocseq, sip_registry::ocseq, sip_registry::opaque, sip_pvt::opaque, option_debug, sip_pvt::our_contact, sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_registry::portno, sip_registry::qop, sip_pvt::qop, sip_registry::realm, sip_pvt::realm, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sched, sip_registry::secret, send_request(), sip_alloc(), sip_debug_test_pvt(), sip_destroy(), sip_methods, SIP_NO_HISTORY, SIP_OUTGOING, sip_reg_timeout(), SIP_REGISTER, sipdebug, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, sip_registry::timeout, sip_pvt::tohost, TRUE, sip_pvt::uri, username, sip_registry::username, sip_pvt::via, and XMIT_CRITICAL.
Referenced by __sip_do_register(), do_register_auth(), and sip_reg_timeout().
07688 { 07689 struct sip_request req; 07690 char from[256]; 07691 char to[256]; 07692 char tmp[80]; 07693 char addr[80]; 07694 struct sip_pvt *p; 07695 char *fromdomain; 07696 07697 /* exit if we are already in process with this registrar ?*/ 07698 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 07699 if (r) { 07700 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 07701 } 07702 return 0; 07703 } 07704 07705 if (r->call) { /* We have a registration */ 07706 if (!auth) { 07707 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 07708 return 0; 07709 } else { 07710 p = r->call; 07711 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 07712 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 07713 } 07714 } else { 07715 /* Build callid for registration if we haven't registered before */ 07716 if (!r->callid_valid) { 07717 build_callid_registry(r, __ourip, default_fromdomain); 07718 r->callid_valid = TRUE; 07719 } 07720 /* Allocate SIP packet for registration */ 07721 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) { 07722 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 07723 return 0; 07724 } 07725 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07726 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 07727 /* Find address to hostname */ 07728 if (create_addr(p, r->hostname)) { 07729 /* we have what we hope is a temporary network error, 07730 * probably DNS. We need to reschedule a registration try */ 07731 sip_destroy(p); 07732 07733 if (r->timeout > -1) 07734 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 07735 else 07736 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); 07737 07738 AST_SCHED_DEL(sched, r->timeout); 07739 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07740 r->regattempts++; 07741 return 0; 07742 } 07743 /* Copy back Call-ID in case create_addr changed it */ 07744 ast_string_field_set(r, callid, p->callid); 07745 if (r->portno) { 07746 p->sa.sin_port = htons(r->portno); 07747 p->recv.sin_port = htons(r->portno); 07748 } else /* Set registry port to the port set from the peer definition/srv or default */ 07749 r->portno = ntohs(p->sa.sin_port); 07750 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 07751 r->call=p; /* Save pointer to SIP packet */ 07752 p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ 07753 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 07754 ast_string_field_set(p, peersecret, r->secret); 07755 if (!ast_strlen_zero(r->md5secret)) 07756 ast_string_field_set(p, peermd5secret, r->md5secret); 07757 /* User name in this realm 07758 - if authuser is set, use that, otherwise use username */ 07759 if (!ast_strlen_zero(r->authuser)) { 07760 ast_string_field_set(p, peername, r->authuser); 07761 ast_string_field_set(p, authname, r->authuser); 07762 } else if (!ast_strlen_zero(r->username)) { 07763 ast_string_field_set(p, peername, r->username); 07764 ast_string_field_set(p, authname, r->username); 07765 ast_string_field_set(p, fromuser, r->username); 07766 } 07767 if (!ast_strlen_zero(r->username)) 07768 ast_string_field_set(p, username, r->username); 07769 /* Save extension in packet */ 07770 ast_string_field_set(p, exten, r->contact); 07771 07772 /* 07773 check which address we should use in our contact header 07774 based on whether the remote host is on the external or 07775 internal network so we can register through nat 07776 */ 07777 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 07778 p->ourip = bindaddr.sin_addr; 07779 build_contact(p); 07780 } 07781 07782 /* set up a timeout */ 07783 if (auth == NULL) { 07784 if (r->timeout > -1) 07785 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 07786 AST_SCHED_DEL(sched, r->timeout); 07787 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07788 if (option_debug) 07789 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 07790 } 07791 07792 if ((fromdomain = strchr(r->username, '@'))) { 07793 /* the domain name is just behind '@' */ 07794 fromdomain++ ; 07795 /* We have a domain in the username for registration */ 07796 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 07797 if (!ast_strlen_zero(p->theirtag)) 07798 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 07799 else 07800 snprintf(to, sizeof(to), "<sip:%s>", r->username); 07801 07802 /* If the registration username contains '@', then the domain should be used as 07803 the equivalent of "fromdomain" for the registration */ 07804 if (ast_strlen_zero(p->fromdomain)) { 07805 ast_string_field_set(p, fromdomain, fromdomain); 07806 } 07807 } else { 07808 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 07809 if (!ast_strlen_zero(p->theirtag)) 07810 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 07811 else 07812 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 07813 } 07814 07815 /* Fromdomain is what we are registering to, regardless of actual 07816 host name from SRV */ 07817 if (!ast_strlen_zero(p->fromdomain)) { 07818 if (r->portno && r->portno != STANDARD_SIP_PORT) 07819 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 07820 else 07821 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 07822 } else { 07823 if (r->portno && r->portno != STANDARD_SIP_PORT) 07824 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 07825 else 07826 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 07827 } 07828 ast_string_field_set(p, uri, addr); 07829 07830 p->branch ^= ast_random(); 07831 07832 init_req(&req, sipmethod, addr); 07833 07834 /* Add to CSEQ */ 07835 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 07836 p->ocseq = r->ocseq; 07837 07838 build_via(p); 07839 add_header(&req, "Via", p->via); 07840 add_header(&req, "From", from); 07841 add_header(&req, "To", to); 07842 add_header(&req, "Call-ID", p->callid); 07843 add_header(&req, "CSeq", tmp); 07844 if (!ast_strlen_zero(global_useragent)) 07845 add_header(&req, "User-Agent", global_useragent); 07846 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07847 07848 07849 if (auth) /* Add auth header */ 07850 add_header(&req, authheader, auth); 07851 else if (!ast_strlen_zero(r->nonce)) { 07852 char digest[1024]; 07853 07854 /* We have auth data to reuse, build a digest header! */ 07855 if (sipdebug) 07856 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 07857 ast_string_field_set(p, realm, r->realm); 07858 ast_string_field_set(p, nonce, r->nonce); 07859 ast_string_field_set(p, domain, r->domain); 07860 ast_string_field_set(p, opaque, r->opaque); 07861 ast_string_field_set(p, qop, r->qop); 07862 r->noncecount++; 07863 p->noncecount = r->noncecount; 07864 07865 memset(digest,0,sizeof(digest)); 07866 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 07867 add_header(&req, "Authorization", digest); 07868 else 07869 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 07870 07871 } 07872 07873 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 07874 add_header(&req, "Expires", tmp); 07875 add_header(&req, "Contact", p->our_contact); 07876 add_header(&req, "Event", "registration"); 07877 add_header_contentLength(&req, 0); 07878 07879 initialize_initreq(p, &req); 07880 if (sip_debug_test_pvt(p)) 07881 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 07882 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 07883 r->regattempts++; /* Another attempt */ 07884 if (option_debug > 3) 07885 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 07886 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07887 }
static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with SDP.
Definition at line 6947 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().
06948 { 06949 struct sip_request req; 06950 06951 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06952 06953 add_header(&req, "Allow", ALLOWED_METHODS); 06954 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06955 if (sipdebug) 06956 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 06957 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 06958 append_history(p, "ReInv", "Re-invite sent"); 06959 add_sdp(&req, p); 06960 /* Use this as the basis */ 06961 initialize_initreq(p, &req); 06962 p->lastinvite = p->ocseq; 06963 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06964 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06965 }
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 6971 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().
06972 { 06973 struct sip_request req; 06974 06975 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06976 06977 add_header(&req, "Allow", ALLOWED_METHODS); 06978 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06979 if (sipdebug) 06980 add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)"); 06981 ast_udptl_offered_from_local(p->udptl, 1); 06982 add_t38_sdp(&req, p); 06983 /* Use this as the basis */ 06984 initialize_initreq(p, &req); 06985 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06986 p->lastinvite = p->ocseq; 06987 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06988 }
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 8003 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().
08004 { 08005 struct sip_request resp; 08006 08007 if (sipmethod == SIP_ACK) 08008 p->invitestate = INV_CONFIRMED; 08009 08010 reqprep(&resp, p, sipmethod, seqno, newbranch); 08011 add_header_contentLength(&resp, 0); 08012 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 08013 }
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 8016 of file chan_sip.c.
References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), ast_strlen_zero(), sip_invite_param::auth_type, build_reply_digest(), sip_pvt::callid, ast_channel::hangupcause, sip_pvt::ocseq, sip_pvt::options, sip_pvt::owner, PROXY_AUTH, sip_pvt::realm, reqprep(), send_request(), SIP_BYE, and WWW_AUTH.
Referenced by __sip_autodestruct(), check_pendings(), and sip_hangup().
08017 { 08018 struct sip_request resp; 08019 08020 reqprep(&resp, p, sipmethod, seqno, newbranch); 08021 if (!ast_strlen_zero(p->realm)) { 08022 char digest[1024]; 08023 08024 memset(digest, 0, sizeof(digest)); 08025 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 08026 if (p->options && p->options->auth_type == PROXY_AUTH) 08027 add_header(&resp, "Proxy-Authorization", digest); 08028 else if (p->options && p->options->auth_type == WWW_AUTH) 08029 add_header(&resp, "Authorization", digest); 08030 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 08031 add_header(&resp, "Proxy-Authorization", digest); 08032 } else 08033 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 08034 } 08035 /* If we are hanging up and know a cause for that, send it in clear text to make 08036 debugging easier. */ 08037 if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) { 08038 char buf[10]; 08039 08040 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 08041 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 08042 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 08043 } 08044 08045 add_header_contentLength(&resp, 0); 08046 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 08047 }
static int transmit_response | ( | struct sip_pvt * | p, | |
const char * | msg, | |||
const struct sip_request * | req | |||
) | [static] |
Transmit response, no retransmits.
Definition at line 6253 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
06254 { 06255 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06256 }
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 6272 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().
06273 { 06274 return __transmit_response(p, msg, req, XMIT_CRITICAL); 06275 }
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 6202 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.
06203 { 06204 struct sip_pvt *p = NULL; 06205 06206 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 06207 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 06208 return -1; 06209 } 06210 06211 /* if the structure was just allocated, initialize it */ 06212 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 06213 ast_set_flag(&p->flags[0], SIP_NO_HISTORY); 06214 if (ast_string_field_init(p, 512)) 06215 return -1; 06216 } 06217 06218 /* Initialize the bare minimum */ 06219 p->method = intended_method; 06220 06221 if (sin) { 06222 p->sa = *sin; 06223 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 06224 p->ourip = __ourip; 06225 } else 06226 p->ourip = __ourip; 06227 06228 p->branch = ast_random(); 06229 make_our_tag(p->tag, sizeof(p->tag)); 06230 p->ocseq = INITIAL_CSEQ; 06231 06232 if (useglobal_nat && sin) { 06233 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 06234 p->recv = *sin; 06235 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 06236 } 06237 check_via(p, req); 06238 06239 ast_string_field_set(p, fromdomain, default_fromdomain); 06240 build_via(p); 06241 ast_string_field_set(p, callid, callid); 06242 06243 /* Use this temporary pvt structure to send the message */ 06244 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 06245 06246 /* Free the string fields, but not the pool space */ 06247 ast_string_field_reset_all(p); 06248 06249 return 0; 06250 }
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 6300 of file chan_sip.c.
References add_header(), add_header_contentLength(), respprep(), and send_response().
Referenced by handle_request(), and handle_request_options().
06301 { 06302 struct sip_request resp; 06303 respprep(&resp, p, msg, req); 06304 add_header(&resp, "Accept", "application/sdp"); 06305 add_header_contentLength(&resp, 0); 06306 return send_response(p, &resp, reliable, 0); 06307 }
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 6310 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().
06311 { 06312 struct sip_request resp; 06313 char tmp[512]; 06314 int seqno = 0; 06315 06316 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 06317 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 06318 return -1; 06319 } 06320 /* Stale means that they sent us correct authentication, but 06321 based it on an old challenge (nonce) */ 06322 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 06323 respprep(&resp, p, msg, req); 06324 add_header(&resp, header, tmp); 06325 add_header_contentLength(&resp, 0); 06326 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 06327 return send_response(p, &resp, reliable, seqno); 06328 }
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 6290 of file chan_sip.c.
References add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
06291 { 06292 struct sip_request resp; 06293 respprep(&resp, p, msg, req); 06294 append_date(&resp); 06295 add_header_contentLength(&resp, 0); 06296 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06297 }
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 6876 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().
06877 { 06878 struct sip_request resp; 06879 int seqno; 06880 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06881 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06882 return -1; 06883 } 06884 respprep(&resp, p, msg, req); 06885 if (p->rtp) { 06886 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06887 if (option_debug) 06888 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 06889 ast_rtp_codec_setpref(p->rtp, &p->prefs); 06890 } 06891 try_suggested_sip_codec(p); 06892 add_sdp(&resp, p); 06893 } else 06894 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 06895 if (reliable && !p->pendinginvite) 06896 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06897 return send_response(p, &resp, reliable, seqno); 06898 }
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 6836 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().
06837 { 06838 struct sip_request resp; 06839 int seqno; 06840 06841 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06842 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06843 return -1; 06844 } 06845 respprep(&resp, p, msg, req); 06846 if (p->udptl) { 06847 ast_udptl_offered_from_local(p->udptl, 0); 06848 add_t38_sdp(&resp, p); 06849 } else 06850 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 06851 if (retrans && !p->pendinginvite) 06852 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06853 return send_response(p, &resp, retrans, seqno); 06854 }
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 6259 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
06260 { 06261 struct sip_request resp; 06262 respprep(&resp, p, msg, req); 06263 append_date(&resp); 06264 add_header(&resp, "Unsupported", unsupported); 06265 add_header_contentLength(&resp, 0); 06266 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 06267 }
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 7552 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().
07553 { 07554 if (!p->initreq.headers) /* Initialize first request before sending */ 07555 initialize_initreq(p, req); 07556 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 07557 }
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 7326 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().
07327 { 07328 char tmp[4000], from[256], to[256]; 07329 char *t = tmp, *c, *mfrom, *mto; 07330 size_t maxbytes = sizeof(tmp); 07331 struct sip_request req; 07332 char hint[AST_MAX_EXTENSION]; 07333 char *statestring = "terminated"; 07334 const struct cfsubscription_types *subscriptiontype; 07335 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 07336 char *pidfstate = "--"; 07337 char *pidfnote= "Ready"; 07338 07339 memset(from, 0, sizeof(from)); 07340 memset(to, 0, sizeof(to)); 07341 memset(tmp, 0, sizeof(tmp)); 07342 07343 switch (state) { 07344 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 07345 statestring = (global_notifyringing) ? "early" : "confirmed"; 07346 local_state = NOTIFY_INUSE; 07347 pidfstate = "busy"; 07348 pidfnote = "Ringing"; 07349 break; 07350 case AST_EXTENSION_RINGING: 07351 statestring = "early"; 07352 local_state = NOTIFY_INUSE; 07353 pidfstate = "busy"; 07354 pidfnote = "Ringing"; 07355 break; 07356 case AST_EXTENSION_INUSE: 07357 statestring = "confirmed"; 07358 local_state = NOTIFY_INUSE; 07359 pidfstate = "busy"; 07360 pidfnote = "On the phone"; 07361 break; 07362 case AST_EXTENSION_BUSY: 07363 statestring = "confirmed"; 07364 local_state = NOTIFY_CLOSED; 07365 pidfstate = "busy"; 07366 pidfnote = "On the phone"; 07367 break; 07368 case AST_EXTENSION_UNAVAILABLE: 07369 statestring = "terminated"; 07370 local_state = NOTIFY_CLOSED; 07371 pidfstate = "away"; 07372 pidfnote = "Unavailable"; 07373 break; 07374 case AST_EXTENSION_ONHOLD: 07375 statestring = "confirmed"; 07376 local_state = NOTIFY_CLOSED; 07377 pidfstate = "busy"; 07378 pidfnote = "On Hold"; 07379 break; 07380 case AST_EXTENSION_NOT_INUSE: 07381 default: 07382 /* Default setting */ 07383 break; 07384 } 07385 07386 subscriptiontype = find_subscription_type(p->subscribed); 07387 07388 /* Check which device/devices we are watching and if they are registered */ 07389 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 07390 char *hint2 = hint, *individual_hint = NULL; 07391 int hint_count = 0, unavailable_count = 0; 07392 07393 while ((individual_hint = strsep(&hint2, "&"))) { 07394 hint_count++; 07395 07396 if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE) 07397 unavailable_count++; 07398 } 07399 07400 /* If none of the hinted devices are registered, we will 07401 * override notification and show no availability. 07402 */ 07403 if (hint_count > 0 && hint_count == unavailable_count) { 07404 local_state = NOTIFY_CLOSED; 07405 pidfstate = "away"; 07406 pidfnote = "Not online"; 07407 } 07408 } 07409 07410 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 07411 c = get_in_brackets(from); 07412 if (strncasecmp(c, "sip:", 4)) { 07413 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07414 return -1; 07415 } 07416 mfrom = strsep(&c, ";"); /* trim ; and beyond */ 07417 07418 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 07419 c = get_in_brackets(to); 07420 if (strncasecmp(c, "sip:", 4)) { 07421 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 07422 return -1; 07423 } 07424 mto = strsep(&c, ";"); /* trim ; and beyond */ 07425 07426 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07427 07428 07429 add_header(&req, "Event", subscriptiontype->event); 07430 add_header(&req, "Content-Type", subscriptiontype->mediatype); 07431 switch(state) { 07432 case AST_EXTENSION_DEACTIVATED: 07433 if (timeout) 07434 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07435 else { 07436 add_header(&req, "Subscription-State", "terminated;reason=probation"); 07437 add_header(&req, "Retry-After", "60"); 07438 } 07439 break; 07440 case AST_EXTENSION_REMOVED: 07441 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 07442 break; 07443 default: 07444 if (p->expiry) 07445 add_header(&req, "Subscription-State", "active"); 07446 else /* Expired */ 07447 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07448 } 07449 switch (p->subscribed) { 07450 case XPIDF_XML: 07451 case CPIM_PIDF_XML: 07452 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07453 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 07454 ast_build_string(&t, &maxbytes, "<presence>\n"); 07455 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 07456 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 07457 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 07458 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 07459 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 07460 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 07461 break; 07462 case PIDF_XML: /* Eyebeam supports this format */ 07463 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 07464 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); 07465 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 07466 if (pidfstate[0] != '-') 07467 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 07468 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 07469 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 07470 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 07471 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 07472 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 07473 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 07474 else 07475 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 07476 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 07477 break; 07478 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 07479 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07480 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); 07481 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 07482 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 07483 else 07484 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 07485 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 07486 if (state == AST_EXTENSION_ONHOLD) { 07487 ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n" 07488 "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n" 07489 "</target>\n</local>\n", mto); 07490 } 07491 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 07492 break; 07493 case NONE: 07494 default: 07495 break; 07496 } 07497 07498 if (t > tmp + sizeof(tmp)) 07499 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07500 07501 add_header_contentLength(&req, strlen(tmp)); 07502 add_line(&req, tmp); 07503 p->pendinginvite = p->ocseq; /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */ 07504 07505 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07506 }
static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 3691 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().
03692 { 03693 int fmt; 03694 const char *codec; 03695 03696 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 03697 if (!codec) 03698 return; 03699 03700 fmt = ast_getformatbyname(codec); 03701 if (fmt) { 03702 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 03703 if (p->jointcapability & fmt) { 03704 p->jointcapability &= fmt; 03705 p->capability &= fmt; 03706 } else 03707 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 03708 } else 03709 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 03710 return; 03711 }
static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 18852 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.
18853 { 18854 struct sip_pvt *p, *pl; 18855 18856 /* First, take us out of the channel type list */ 18857 ast_channel_unregister(&sip_tech); 18858 18859 /* Unregister dial plan functions */ 18860 ast_custom_function_unregister(&sipchaninfo_function); 18861 ast_custom_function_unregister(&sippeer_function); 18862 ast_custom_function_unregister(&sip_header_function); 18863 ast_custom_function_unregister(&checksipdomain_function); 18864 18865 /* Unregister dial plan applications */ 18866 ast_unregister_application(app_dtmfmode); 18867 ast_unregister_application(app_sipaddheader); 18868 18869 /* Unregister CLI commands */ 18870 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 18871 18872 /* Disconnect from the RTP subsystem */ 18873 ast_rtp_proto_unregister(&sip_rtp); 18874 18875 /* Disconnect from UDPTL */ 18876 ast_udptl_proto_unregister(&sip_udptl); 18877 18878 /* Unregister AMI actions */ 18879 ast_manager_unregister("SIPpeers"); 18880 ast_manager_unregister("SIPshowpeer"); 18881 18882 ast_mutex_lock(&iflock); 18883 /* Hangup all interfaces if they have an owner */ 18884 for (p = iflist; p ; p = p->next) { 18885 if (p->owner) 18886 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 18887 } 18888 ast_mutex_unlock(&iflock); 18889 18890 ast_mutex_lock(&monlock); 18891 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 18892 pthread_cancel(monitor_thread); 18893 pthread_kill(monitor_thread, SIGURG); 18894 pthread_join(monitor_thread, NULL); 18895 } 18896 monitor_thread = AST_PTHREADT_STOP; 18897 ast_mutex_unlock(&monlock); 18898 18899 restartdestroy: 18900 ast_mutex_lock(&iflock); 18901 /* Destroy all the interfaces and free their memory */ 18902 p = iflist; 18903 while (p) { 18904 pl = p; 18905 p = p->next; 18906 if (__sip_destroy(pl, TRUE) < 0) { 18907 /* Something is still bridged, let it react to getting a hangup */ 18908 iflist = p; 18909 ast_mutex_unlock(&iflock); 18910 usleep(1); 18911 goto restartdestroy; 18912 } 18913 } 18914 iflist = NULL; 18915 ast_mutex_unlock(&iflock); 18916 18917 /* Free memory for local network address mask */ 18918 ast_free_ha(localaddr); 18919 18920 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 18921 ASTOBJ_CONTAINER_DESTROY(&userl); 18922 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 18923 ASTOBJ_CONTAINER_DESTROY(&peerl); 18924 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 18925 ASTOBJ_CONTAINER_DESTROY(®l); 18926 18927 clear_realm_authentication(authl); 18928 clear_sip_domains(); 18929 close(sipsock); 18930 sched_context_destroy(sched); 18931 18932 return 0; 18933 }
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 3242 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().
03243 { 03244 char name[256]; 03245 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 03246 int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL); 03247 struct sip_user *u = NULL; 03248 struct sip_peer *p = NULL; 03249 03250 if (option_debug > 2) 03251 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 03252 03253 /* Test if we need to check call limits, in order to avoid 03254 realtime lookups if we do not need it */ 03255 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD)) 03256 return 0; 03257 03258 ast_copy_string(name, fup->username, sizeof(name)); 03259 03260 /* Check the list of users only for incoming calls */ 03261 if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) { 03262 inuse = &u->inUse; 03263 call_limit = &u->call_limit; 03264 inringing = NULL; 03265 } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1, 0) ) ) { /* Try to find peer */ 03266 inuse = &p->inUse; 03267 call_limit = &p->call_limit; 03268 inringing = &p->inRinging; 03269 ast_copy_string(name, fup->peername, sizeof(name)); 03270 } 03271 if (!p && !u) { 03272 if (option_debug > 1) 03273 ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name); 03274 return 0; 03275 } 03276 03277 switch(event) { 03278 /* incoming and outgoing affects the inUse counter */ 03279 case DEC_CALL_LIMIT: 03280 if ( *inuse > 0 ) { 03281 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 03282 (*inuse)--; 03283 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 03284 } 03285 } else { 03286 *inuse = 0; 03287 } 03288 if (inringing) { 03289 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03290 if (*inringing > 0) 03291 (*inringing)--; 03292 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03293 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername); 03294 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03295 } 03296 } 03297 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) { 03298 ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD); 03299 sip_peer_hold(fup, 0); 03300 } 03301 if (option_debug > 1 || sipdebug) { 03302 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 03303 } 03304 break; 03305 03306 case INC_CALL_RINGING: 03307 case INC_CALL_LIMIT: 03308 if (*call_limit > 0 ) { 03309 /* Let call limit affect only outgoing calls */ 03310 if (outgoing && (*inuse >= *call_limit)) { 03311 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); 03312 if (u) 03313 ASTOBJ_UNREF(u, sip_destroy_user); 03314 else 03315 ASTOBJ_UNREF(p, sip_destroy_peer); 03316 return -1; 03317 } 03318 } 03319 if (inringing && (event == INC_CALL_RINGING)) { 03320 if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03321 (*inringing)++; 03322 ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03323 } 03324 } 03325 /* Continue */ 03326 (*inuse)++; 03327 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 03328 if (option_debug > 1 || sipdebug) { 03329 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 03330 } 03331 break; 03332 03333 case DEC_CALL_RINGING: 03334 if (inringing) { 03335 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03336 if (*inringing > 0) 03337 (*inringing)--; 03338 else if (!ast_test_flag(&p->flags[0], SIP_REALTIME) || ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) 03339 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name); 03340 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03341 } 03342 } 03343 break; 03344 03345 default: 03346 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 03347 } 03348 if (p) { 03349 ast_device_state_changed("SIP/%s", p->name); 03350 ASTOBJ_UNREF(p, sip_destroy_peer); 03351 } else /* u must be set */ 03352 ASTOBJ_UNREF(u, sip_destroy_user); 03353 return 0; 03354 }
static void update_peer | ( | struct sip_peer * | p, | |
int | expiry | |||
) | [static] |
Update peer data in database (if used).
Definition at line 2517 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, sip_peer::fullcontact, global_flags, sip_peer::name, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_REALTIME, and sip_peer::username.
Referenced by register_verify().
02518 { 02519 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02520 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) && 02521 (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) { 02522 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry); 02523 } 02524 }
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 18939 of file chan_sip.c.
struct in_addr __ourip [static] |
Definition at line 1226 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 18416 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 18418 of file chan_sip.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 18939 of file chan_sip.c.
Definition at line 1215 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 1220 of file chan_sip.c.
struct ast_threadstorage check_auth_buf = { .once = PTHREAD_ONCE_INIT , .key_init = check_auth_buf_init , } [static] |
struct ast_custom_function checksipdomain_function [static] |
struct ast_cli_entry cli_sip[] [static] |
struct ast_cli_entry cli_sip_debug_deprecated [static] |
Initial value:
{ { "sip", "debug", NULL }, sip_do_debug_deprecated, "Enable SIP debugging", debug_usage }
Definition at line 18678 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 18683 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 11927 of file chan_sip.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1229 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 18415 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 18421 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 1223 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 1222 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 1221 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 11944 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 1225 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 10556 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 10107 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 11936 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 11940 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 1231 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 11876 of file chan_sip.c.
int ourport [static] |
Definition at line 1228 of file chan_sip.c.
struct sockaddr_in outboundproxyip [static] |
Definition at line 1227 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 11918 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 11900 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 11896 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 11871 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 11904 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 11891 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 11957 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 11913 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 11908 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 11923 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 11961 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 11953 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 11886 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 11881 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 11949 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 1628 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 1570 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 1596 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 1637 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 12202 of file chan_sip.c.
Referenced by load_module(), and unload_module().
Structure to declare a dialplan function: SIPPEER.
Definition at line 12122 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 1219 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 18414 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 18419 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.