#include "asterisk.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <regex.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/compiler.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"
Include dependency graph for chan_sip.c:

Go to the source code of this file.
Data Structures | |
| struct | ast_peer_list |
| The peer list: Peers and Friends. More... | |
| struct | ast_register_list |
| The register list: Other SIP proxys we register with and place calls to. More... | |
| struct | ast_user_list |
| The user list: Users and friends. More... | |
| struct | c_referstatusstring |
| struct | cfsip_methods |
| struct | cfsip_options |
| List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More... | |
| struct | cfsubscription_types |
| struct | domain |
| Domain data structure. More... | |
| struct | sip_auth |
| sip_auth: Credentials for authentication to other SIP services More... | |
| struct | sip_dual |
| structure used in transfers More... | |
| struct | sip_history |
| sip_history: Structure for saving transactions within a SIP dialog More... | |
| struct | sip_invite_param |
| Parameters to the transmit_invite function. More... | |
| struct | sip_peer |
| Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host). More... | |
| struct | sip_pkt |
| sip packet - raw format for outbound packets that are sent or scheduled for transmission More... | |
| struct | sip_pvt |
| sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe More... | |
| struct | sip_refer |
| Structure to handle SIP transfers. Dynamically allocated when needed. More... | |
| struct | sip_registry |
| Registrations with other SIP proxies. More... | |
| struct | sip_request |
| sip_request: The data grabbed from the UDP socket More... | |
| struct | sip_route |
| Structure to save routing information for a SIP session. More... | |
| struct | sip_user |
| Structure for SIP user data. User's place calls to us. More... | |
| struct | t38properties |
| T.38 channel settings (at some point we need to make this alloc'ed. More... | |
Defines | |
| #define | ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
| SIP Methods we support. | |
| #define | append_history(p, event, fmt, args...) append_history_full(p, "%-15s " fmt, event, ## args) |
| Append to SIP dialog history. | |
| #define | CALLERID_UNKNOWN "Unknown" |
| #define | CAN_CREATE_DIALOG 1 |
| #define | CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
| #define | CAN_NOT_CREATE_DIALOG 0 |
| #define | DEC_CALL_LIMIT 0 |
| #define | DEC_CALL_RINGING 2 |
| #define | DEFAULT_ALLOW_EXT_DOM TRUE |
| #define | DEFAULT_ALLOWGUEST TRUE |
| #define | DEFAULT_AUTOCREATEPEER FALSE |
| #define | DEFAULT_CALLERID "asterisk" |
| #define | DEFAULT_COMPACTHEADERS FALSE |
| #define | DEFAULT_CONTEXT "default" |
| #define | DEFAULT_DEFAULT_EXPIRY 120 |
| #define | DEFAULT_EXPIRY 900 |
| #define | DEFAULT_FREQ_NOTOK 10 * 1000 |
| #define | DEFAULT_FREQ_OK 60 * 1000 |
| #define | DEFAULT_MAX_CALL_BITRATE (384) |
| #define | DEFAULT_MAX_EXPIRY 3600 |
| #define | DEFAULT_MAX_FORWARDS "70" |
| #define | DEFAULT_MAXMS 2000 |
| #define | DEFAULT_MIN_EXPIRY 60 |
| #define | DEFAULT_MOHINTERPRET "default" |
| #define | DEFAULT_MOHSUGGEST "" |
| #define | DEFAULT_MWITIME 10 |
| #define | DEFAULT_NOTIFYMIME "application/simple-message-summary" |
| #define | DEFAULT_NOTIFYRINGING TRUE |
| #define | DEFAULT_PEDANTIC FALSE |
| #define | DEFAULT_QUALIFY FALSE |
| #define | DEFAULT_REALM "asterisk" |
| #define | DEFAULT_REGISTRATION_TIMEOUT 20 |
| #define | DEFAULT_RETRANS 1000 |
| #define | DEFAULT_SRVLOOKUP FALSE |
| #define | DEFAULT_T1MIN 100 |
| #define | DEFAULT_TOS_AUDIO 0 |
| #define | DEFAULT_TOS_SIP 0 |
| #define | DEFAULT_TOS_VIDEO 0 |
| #define | DEFAULT_TRANS_TIMEOUT -1 |
| #define | DEFAULT_USERAGENT "Asterisk PBX" |
| #define | DEFAULT_VMEXTEN "asterisk" |
| #define | EXPIRY_GUARD_LIMIT 30 |
| #define | EXPIRY_GUARD_MIN 500 |
| #define | EXPIRY_GUARD_PCT 0.20 |
| #define | EXPIRY_GUARD_SECS 15 |
| #define | FALSE 0 |
| #define | FLAG_FATAL (1 << 1) |
| #define | FLAG_RESPONSE (1 << 0) |
| #define | FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s %-10.10s\n" |
| #define | FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" |
| #define | FORMAT "%-40.40s %-20.20s %-16.16s\n" |
| #define | FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" |
| #define | FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
| #define | FORMAT "%-25.25s %-15.15s %-15.15s \n" |
| #define | FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-4.4s %-7.7s %-15.15s\n" |
| #define | FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
| #define | FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" |
| #define | FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
| #define | FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" |
| #define | INC_CALL_LIMIT 1 |
| #define | INC_CALL_RINGING 3 |
| #define | INITIAL_CSEQ 101 |
| #define | IPTOS_MINCOST 0x02 |
| #define | MAX(a, b) ((a) > (b) ? (a) : (b)) |
| #define | MAX_AUTHTRIES 3 |
| #define | MAX_RETRANS 6 |
| #define | NO_RTP 0 |
| #define | NOT_SUPPORTED 0 |
| #define | RTP 1 |
| #define | SDP_SAMPLE_RATE(x) (x == AST_FORMAT_G722) ? 16000 : 8000 |
| #define | SIP_ALREADYGONE (1 << 0) |
| #define | SIP_CALL_LIMIT (1 << 28) |
| #define | SIP_CAN_REINVITE (1 << 20) |
| #define | SIP_CAN_REINVITE_NAT (2 << 20) |
| #define | SIP_DEFER_BYE_ON_TRANSFER (1 << 15) |
| #define | SIP_DTMF (3 << 16) |
| #define | SIP_DTMF_AUTO (3 << 16) |
| #define | SIP_DTMF_INBAND (1 << 16) |
| #define | SIP_DTMF_INFO (2 << 16) |
| #define | SIP_DTMF_RFC2833 (0 << 16) |
| #define | SIP_FLAGS_TO_COPY |
| #define | SIP_FREE_BIT (1 << 14) |
| #define | SIP_G726_NONSTANDARD (1 << 31) |
| #define | SIP_GOTREFER (1 << 7) |
| #define | SIP_INC_COUNT (1 << 30) |
| #define | SIP_INSECURE_INVITE (1 << 24) |
| #define | SIP_INSECURE_PORT (1 << 23) |
| #define | SIP_MAX_HEADERS 64 |
| #define | SIP_MAX_LINES 64 |
| #define | SIP_MAX_PACKET 4096 |
| #define | SIP_NAT (3 << 18) |
| #define | SIP_NAT_ALWAYS (3 << 18) |
| #define | SIP_NAT_NEVER (0 << 18) |
| #define | SIP_NAT_RFC3581 (1 << 18) |
| #define | SIP_NAT_ROUTE (2 << 18) |
| #define | SIP_NEEDDESTROY (1 << 1) |
| #define | SIP_NEEDREINVITE (1 << 5) |
| #define | SIP_NO_HISTORY (1 << 27) |
| #define | SIP_NOVIDEO (1 << 2) |
| #define | SIP_OPT_100REL (1 << 1) |
| #define | SIP_OPT_EARLY_SESSION (1 << 3) |
| #define | SIP_OPT_EVENTLIST (1 << 11) |
| #define | SIP_OPT_GRUU (1 << 12) |
| #define | SIP_OPT_HISTINFO (1 << 15) |
| #define | SIP_OPT_JOIN (1 << 4) |
| #define | SIP_OPT_NOREFERSUB (1 << 14) |
| #define | SIP_OPT_PATH (1 << 5) |
| #define | SIP_OPT_PRECONDITION (1 << 7) |
| #define | SIP_OPT_PREF (1 << 6) |
| #define | SIP_OPT_PRIVACY (1 << 8) |
| #define | SIP_OPT_REPLACES (1 << 0) |
| #define | SIP_OPT_RESPRIORITY (1 << 16) |
| #define | SIP_OPT_SDP_ANAT (1 << 9) |
| #define | SIP_OPT_SEC_AGREE (1 << 10) |
| #define | SIP_OPT_TARGET_DIALOG (1 << 13) |
| #define | SIP_OPT_TIMER (1 << 2) |
| #define | SIP_OUTGOING (1 << 13) |
| #define | SIP_PAGE2_ALLOWOVERLAP (1 << 17) |
| #define | SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
| #define | SIP_PAGE2_BUGGY_MWI (1 << 26) |
| #define | SIP_PAGE2_CALL_ONHOLD (3 << 23) |
| #define | SIP_PAGE2_CALL_ONHOLD_INACTIVE (1 << 24) |
| #define | SIP_PAGE2_CALL_ONHOLD_ONEDIR (1 << 23) |
| #define | SIP_PAGE2_DEBUG (3 << 11) |
| #define | SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
| #define | SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
| #define | SIP_PAGE2_DYNAMIC (1 << 13) |
| #define | SIP_PAGE2_FLAGS_TO_COPY |
| #define | SIP_PAGE2_IGNOREREGEXPIRE (1 << 10) |
| #define | SIP_PAGE2_INC_RINGING (1 << 19) |
| #define | SIP_PAGE2_OUTGOING_CALL (1 << 27) |
| #define | SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) |
| #define | SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
| #define | SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
| #define | SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
| #define | SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
| #define | SIP_PAGE2_RTUPDATE (1 << 1) |
| #define | SIP_PAGE2_SELFDESTRUCT (1 << 14) |
| #define | SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
| #define | SIP_PAGE2_T38SUPPORT (7 << 20) |
| #define | SIP_PAGE2_T38SUPPORT_RTP (2 << 20) |
| #define | SIP_PAGE2_T38SUPPORT_TCP (4 << 20) |
| #define | SIP_PAGE2_T38SUPPORT_UDPTL (1 << 20) |
| #define | SIP_PAGE2_VIDEOSUPPORT (1 << 15) |
| #define | SIP_PENDINGBYE (1 << 6) |
| #define | SIP_PKT_DEBUG (1 << 0) |
| #define | SIP_PKT_IGNORE (1 << 2) |
| #define | SIP_PKT_IGNORE_REQ (1 << 4) |
| #define | SIP_PKT_IGNORE_RESP (1 << 3) |
| #define | SIP_PKT_WITH_TOTAG (1 << 1) |
| #define | SIP_PROG_INBAND (3 << 25) |
| #define | SIP_PROG_INBAND_NEVER (0 << 25) |
| #define | SIP_PROG_INBAND_NO (1 << 25) |
| #define | SIP_PROG_INBAND_YES (2 << 25) |
| #define | SIP_PROGRESS_SENT (1 << 4) |
| #define | SIP_PROMISCREDIR (1 << 8) |
| #define | SIP_REALTIME (1 << 11) |
| #define | SIP_REINVITE (7 << 20) |
| #define | SIP_REINVITE_UPDATE (4 << 20) |
| #define | SIP_RINGING (1 << 3) |
| #define | SIP_SENDRPID (1 << 29) |
| #define | SIP_TRANS_TIMEOUT 32000 |
| #define | SIP_TRUSTRPID (1 << 9) |
| #define | SIP_USECLIENTCODE (1 << 12) |
| #define | SIP_USEREQPHONE (1 << 10) |
| #define | sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG) |
| #define | sipdebug_config ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG) |
| #define | sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
| #define | STANDARD_SIP_PORT 5060 |
| Standard SIP port from RFC 3261. DO NOT CHANGE THIS. | |
| #define | SUPPORTED 1 |
| #define | SUPPORTED_EXTENSIONS "replaces" |
| SIP Extensions we support. | |
| #define | T38FAX_FILL_BIT_REMOVAL (1 << 0) |
| #define | T38FAX_RATE_12000 (1 << 12) |
| #define | T38FAX_RATE_14400 (1 << 13) |
| #define | T38FAX_RATE_2400 (1 << 8) |
| #define | T38FAX_RATE_4800 (1 << 9) |
| #define | T38FAX_RATE_7200 (1 << 10) |
| #define | T38FAX_RATE_9600 (1 << 11) |
| #define | T38FAX_RATE_MANAGEMENT_LOCAL_TCF (1 << 3) |
| #define | T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
| #define | T38FAX_TRANSCODING_JBIG (1 << 2) |
| #define | T38FAX_TRANSCODING_MMR (1 << 1) |
| #define | T38FAX_UDP_EC_FEC (1 << 4) |
| #define | T38FAX_UDP_EC_NONE (0 << 4) |
| #define | T38FAX_UDP_EC_REDUNDANCY (2 << 4) |
| #define | T38FAX_VERSION (3 << 6) |
| #define | T38FAX_VERSION_0 (0 << 6) |
| #define | T38FAX_VERSION_1 (1 << 6) |
| #define | TRUE 1 |
| #define | UNLINK(element, head, prev) |
| #define | VIDEO_CODEC_MASK 0x1fc0000 |
Enumerations | |
| enum | check_auth_result { AUTH_SUCCESSFUL = 0, AUTH_CHALLENGE_SENT = 1, AUTH_SECRET_FAILED = -1, AUTH_USERNAME_MISMATCH = -2, AUTH_NOT_FOUND = -3, AUTH_FAKE_AUTH = -4, AUTH_UNKNOWN_DOMAIN = -5 } |
| Authentication result from check_auth* functions. More... | |
| enum | domain_mode { SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG } |
| Modes for SIP domain handling in the PBX. More... | |
| enum | invitestates { INV_NONE = 0, INV_CALLING = 1, INV_PROCEEDING = 2, INV_EARLY_MEDIA = 3, INV_COMPLETED = 4, INV_CONFIRMED = 5, INV_TERMINATED = 6, INV_CANCELLED = 7 } |
| States for the INVITE transaction, not the dialog. More... | |
| enum | parse_register_result { PARSE_REGISTER_FAILED, PARSE_REGISTER_UPDATE, PARSE_REGISTER_QUERY } |
| enum | referstatus { REFER_IDLE, REFER_SENT, REFER_RECEIVED, REFER_CONFIRMED, REFER_ACCEPTED, REFER_RINGING, REFER_200OK, REFER_FAILED, REFER_NOAUTH } |
| Parameters to know status of transfer. More... | |
| enum | sip_auth_type { PROXY_AUTH, WWW_AUTH } |
| Authentication types - proxy or www authentication. More... | |
| enum | sip_result { AST_SUCCESS = 0, AST_FAILURE = -1 } |
| enum | sipmethod { SIP_UNKNOWN, SIP_RESPONSE, SIP_REGISTER, SIP_OPTIONS, SIP_NOTIFY, SIP_INVITE, SIP_ACK, SIP_PRACK, SIP_BYE, SIP_REFER, SIP_SUBSCRIBE, SIP_MESSAGE, SIP_UPDATE, SIP_INFO, SIP_CANCEL, SIP_PUBLISH, SIP_PING } |
| SIP Request methods known by Asterisk. More... | |
| enum | sipregistrystate { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH, REG_STATE_FAILED } |
| States for outbound registrations (with register= lines in sip.conf. More... | |
| enum | subscriptiontype { NONE = 0, XPIDF_XML, DIALOG_INFO_XML, CPIM_PIDF_XML, PIDF_XML, MWI_NOTIFICATION } |
| enum | t38state { T38_DISABLED = 0, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, T38_PEER_DIRECT, T38_PEER_REINVITE, T38_ENABLED } |
| T38 States for a call. More... | |
| enum | transfermodes { TRANSFER_OPENFORALL, TRANSFER_CLOSED } |
| Authorization scheme for call transfers. More... | |
| enum | xmittype { XMIT_CRITICAL = 2, XMIT_RELIABLE = 1, XMIT_UNRELIABLE = 0 } |
Functions | |
| static const char * | __get_header (const struct sip_request *req, const char *name, int *start) |
| static void | __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
| Acknowledges receipt of a packet and stops retransmission. | |
| static int | __sip_autodestruct (void *data) |
| Kill a SIP dialog (called by scheduler). | |
| static void | __sip_destroy (struct sip_pvt *p, int lockowner) |
| Execute destruction of SIP dialog structure, release memory. | |
| static int | __sip_do_register (struct sip_registry *r) |
| Register with SIP proxy. | |
| static void | __sip_pretend_ack (struct sip_pvt *p) |
| Pretend to ack all packets maybe the lock on p is not strictly necessary but there might be a race. | |
| static int | __sip_reliable_xmit (struct sip_pvt *p, int seqno, int resp, char *data, int len, int fatal, int sipmethod) |
| Transmit packet with retransmits. | |
| static int | __sip_semi_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod) |
| Acks receipt of packet, keep it around (used for provisional responses). | |
| static int | __sip_show_channels (int fd, int argc, char *argv[], int subscriptions) |
| SIP show channels CLI (main function). | |
| static int | __sip_xmit (struct sip_pvt *p, char *data, int len) |
| Transmit SIP message. | |
| static int | __transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
| Base transmit response function. | |
| static int | _sip_show_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
| Show one peer in detail (main function). | |
| static int | _sip_show_peers (int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[]) |
| _sip_show_peers: Execute sip show peers command | |
| static int | acf_channel_read (struct ast_channel *chan, char *funcname, char *preparse, char *buf, size_t buflen) |
| static void | add_blank (struct sip_request *req) |
| add a blank line if no body | |
| static void | add_codec_to_sdp (const struct sip_pvt *p, int codec, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug, int *min_packet_size) |
| Add codec offer to SDP offer/answer body in INVITE or 200 OK. | |
| static int | add_digit (struct sip_request *req, char digit, unsigned int duration) |
| Add DTMF INFO tone to sip message. | |
| static int | add_header (struct sip_request *req, const char *var, const char *value) |
| Add header to SIP message. | |
| static int | add_header_contentLength (struct sip_request *req, int len) |
| Add 'Content-Length' header to SIP message. | |
| static int | add_line (struct sip_request *req, const char *line) |
| Add content (not header) to SIP message. | |
| static void | add_noncodec_to_sdp (const struct sip_pvt *p, int format, int sample_rate, char **m_buf, size_t *m_size, char **a_buf, size_t *a_size, int debug) |
| Add RFC 2833 DTMF offer to SDP. | |
| static struct sip_auth * | add_realm_authentication (struct sip_auth *authlist, char *configuration, int lineno) |
| Add realm authentication in list. | |
| static void | add_route (struct sip_request *req, struct sip_route *route) |
| Add route header into request per learned route. | |
| static enum sip_result | add_sdp (struct sip_request *resp, struct sip_pvt *p) |
| Add Session Description Protocol message. | |
| static int | add_sip_domain (const char *domain, const enum domain_mode mode, const char *context) |
| Add SIP domain to list of domains we are responsible for. | |
| static int | add_t38_sdp (struct sip_request *resp, struct sip_pvt *p) |
| Add T.38 Session Description Protocol message. | |
| static int | add_text (struct sip_request *req, const char *text) |
| Add text body to SIP message. | |
| static int | add_vidupdate (struct sip_request *req) |
| add XML encoded media control with update | |
| static void | append_date (struct sip_request *req) |
| Append date to SIP message. | |
| static void | append_history_full (struct sip_pvt *p, const char *fmt,...) |
| Append to SIP dialog history with arg list. | |
| static void static void | append_history_va (struct sip_pvt *p, const char *fmt, va_list ap) |
| Append to SIP dialog history with arg list. | |
| AST_LIST_HEAD_NOLOCK (sip_history_head, sip_history) | |
| static | AST_LIST_HEAD_STATIC (domain_list, domain) |
| AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Session Initiation Protocol (SIP)",.load=load_module,.unload=unload_module,.reload=reload,) | |
| AST_MUTEX_DEFINE_STATIC (sip_reload_lock) | |
| AST_MUTEX_DEFINE_STATIC (monlock) | |
| AST_MUTEX_DEFINE_STATIC (netlock) | |
| Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical. | |
| AST_MUTEX_DEFINE_STATIC (iflock) | |
| Protect the SIP dialog list (of sip_pvt's). | |
| static void | ast_quiet_chan (struct ast_channel *chan) |
| Turn off generator data XXX Does this function belong in the SIP channel? | |
| static int | ast_sip_ouraddrfor (struct in_addr *them, struct in_addr *us) |
| NAT fix - decide which IP address to use for ASterisk server? | |
| AST_THREADSTORAGE_CUSTOM (ts_temp_pvt, temp_pvt_init, temp_pvt_cleanup) | |
| A per-thread temporary pvt structure. | |
| static int | attempt_transfer (struct sip_dual *transferer, struct sip_dual *target) |
| Attempt transfer of SIP call This fix for attended transfers on a local PBX. | |
| static int | auto_congest (void *nothing) |
| Scheduled congestion on a call. | |
| static void | build_callid_pvt (struct sip_pvt *pvt) |
| Build SIP Call-ID value for a non-REGISTER transaction. | |
| static void | build_callid_registry (struct sip_registry *reg, struct in_addr ourip, const char *fromdomain) |
| Build SIP Call-ID value for a REGISTER transaction. | |
| static void | build_contact (struct sip_pvt *p) |
| Build contact header - the contact header we send out. | |
| static struct sip_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
| Build peer from configuration (file or realtime static/dynamic). | |
| static int | build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len) |
| Build reply digest. | |
| static void | build_route (struct sip_pvt *p, struct sip_request *req, int backwards) |
| Build route list from Record-Route header. | |
| static void | build_rpid (struct sip_pvt *p) |
| Build the Remote Party-ID & From using callingpres options. | |
| static struct sip_user * | build_user (const char *name, struct ast_variable *v, int realtime) |
| Initiate a SIP user structure from configuration (configuration or realtime). | |
| static void | build_via (struct sip_pvt *p) |
| Build a Via header for a request. | |
| static int | cb_extensionstate (char *context, char *exten, int state, void *data) |
| Callback for the devicestate notification (SUBSCRIBE) support subsystem. | |
| static enum check_auth_result | check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, char *uri, enum xmittype reliable, int ignore) |
| Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set). | |
| static void | check_pendings (struct sip_pvt *p) |
| Check pending actions on SIP call. | |
| static int | check_sip_domain (const char *domain, char *context, size_t len) |
| check_sip_domain: Check if domain part of uri is local to our server | |
| static int | check_user (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin) |
| Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced. | |
| static enum check_auth_result | check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin, struct sip_peer **authpeer) |
| Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests. | |
| static void | check_via (struct sip_pvt *p, struct sip_request *req) |
| check Via: header for hostname, port and rport request/answer | |
| static void | cleanup_stale_contexts (char *new, char *old) |
| Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly. | |
| static int | clear_realm_authentication (struct sip_auth *authlist) |
| Clear realm authentication list (at reload). | |
| static void | clear_sip_domains (void) |
| Clear our domain list (at reload). | |
| static char * | complete_sip_debug_peer (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip debug peer' CLI. | |
| static char * | complete_sip_peer (const char *word, int state, int flags2) |
| Do completion on peer name. | |
| static char * | complete_sip_prune_realtime_peer (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip prune realtime peer' CLI. | |
| static char * | complete_sip_prune_realtime_user (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip prune realtime user' CLI. | |
| static char * | complete_sip_show_peer (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip show peer' CLI. | |
| static char * | complete_sip_show_user (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip show user' CLI. | |
| static char * | complete_sip_user (const char *word, int state, int flags2) |
| Do completion on user name. | |
| static char * | complete_sipch (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip show channel' CLI. | |
| static char * | complete_sipnotify (const char *line, const char *word, int pos, int state) |
| Support routine for 'sip notify' CLI. | |
| static int | copy_all_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
| Copy all headers from one request to another. | |
| static int | copy_header (struct sip_request *req, const struct sip_request *orig, const char *field) |
| Copy one header field from one request to another. | |
| static void | copy_request (struct sip_request *dst, const struct sip_request *src) |
| copy SIP request (mostly used to save request for responses) | |
| static int | copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field) |
| Copy SIP VIA Headers from the request to the response. | |
| static int | create_addr (struct sip_pvt *dialog, const char *opeer) |
| create address structure from peer name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success | |
| static int | create_addr_from_peer (struct sip_pvt *dialog, struct sip_peer *peer) |
| Create address structure from peer reference. return -1 on error, 0 on success. | |
| static void | destroy_association (struct sip_peer *peer) |
| Remove registration data from realtime database or AST/DB when registration expires. | |
| static int | determine_firstline_parts (struct sip_request *req) |
| Parse first line of incoming SIP request. | |
| static void * | do_monitor (void *data) |
| The SIP monitoring thread. | |
| static int | do_proxy_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader, int sipmethod, int init) |
| Add authentication on outbound SIP packet. | |
| static int | do_register_auth (struct sip_pvt *p, struct sip_request *req, char *header, char *respheader) |
| Authenticate for outbound registration. | |
| static void | do_setnat (struct sip_pvt *p, int natflags) |
| Set nat mode on the various data sockets. | |
| static int | does_peer_need_mwi (struct sip_peer *peer) |
| Check whether peer needs a new MWI notification check. | |
| static const char * | domain_mode_to_text (const enum domain_mode mode) |
| Print domain mode to cli. | |
| static const char * | dtmfmode2str (int mode) |
| Convert DTMF mode to printable string. | |
| static int | expire_register (void *data) |
| Expire registration of SIP peer. | |
| static void | extract_uri (struct sip_pvt *p, struct sip_request *req) |
| Check Contact: URI of SIP message. | |
| static const char * | find_alias (const char *name, const char *_default) |
| Find compressed SIP alias. | |
| static struct sip_pvt * | find_call (struct sip_request *req, struct sockaddr_in *sin, const int intended_method) |
| Connect incoming SIP message to current dialog or create new dialog structure Called by handle_request, sipsock_read. | |
| static const char * | find_closing_quote (const char *start, const char *lim) |
| Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote. | |
| static struct sip_peer * | find_peer (const char *peer, struct sockaddr_in *sin, int realtime) |
| Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name. | |
| static struct sip_auth * | find_realm_authentication (struct sip_auth *authlist, const char *realm) |
| Find authentication for a specific realm. | |
| static int | find_sdp (struct sip_request *req) |
| Determine whether a SIP message contains an SDP in its body. | |
| static int | find_sip_method (const char *msg) |
| find_sip_method: Find SIP method from header | |
| static struct cfsubscription_types * | find_subscription_type (enum subscriptiontype subtype) |
| Find subscription type in array. | |
| static struct sip_user * | find_user (const char *name, int realtime) |
| Locate user by name Locates user by name (From: sip uri user name part) first from in-memory list (static configuration) then from realtime storage (defined in extconfig.conf). | |
| static void | free_old_route (struct sip_route *route) |
| Remove route from route list. | |
| static int | func_check_sipdomain (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
| Dial plan function to check if domain is local. | |
| static int | func_header_read (struct ast_channel *chan, char *function, char *data, char *buf, size_t len) |
| Read SIP header (dialplan function). | |
| static int | function_sipchaninfo_read (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
| ${SIPCHANINFO()} Dialplan function - reads sip channel data | |
| static int | function_sippeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
| ${SIPPEER()} Dialplan function - reads peer data | |
| static char * | generate_random_string (char *buf, size_t size) |
| Generate 32 byte random string for callid's etc. | |
| static int | get_also_info (struct sip_pvt *p, struct sip_request *oreq) |
| Call transfer support (old way, deprecated by the IETF)--. | |
| static char * | get_body (struct sip_request *req, char *name) |
| Get a specific line from the message body. | |
| static char * | get_body_by_line (const char *line, const char *name, int nameLen) |
| Reads one line of SIP message body. | |
| static char * | get_calleridname (const char *input, char *output, size_t outputsize) |
| Get caller id name from SIP headers. | |
| static int | get_destination (struct sip_pvt *p, struct sip_request *oreq) |
| Find out who the call is for We use the INVITE uri to find out. | |
| static const char * | get_header (const struct sip_request *req, const char *name) |
| Get header from SIP request. | |
| static char * | get_in_brackets (char *tmp) |
| Pick out text in brackets from character string. | |
| static int | get_msg_text (char *buf, int len, struct sip_request *req) |
| Get text out of a SIP MESSAGE packet. | |
| static int | get_rdnis (struct sip_pvt *p, struct sip_request *oreq) |
| Get referring dnis. | |
| static int | get_refer_info (struct sip_pvt *transferer, struct sip_request *outgoing_req) |
| Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure. | |
| static int | get_rpid_num (const char *input, char *output, int maxlen) |
| Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found. | |
| static const char * | get_sdp (struct sip_request *req, const char *name) |
| Get a line from an SDP message body. | |
| static const char * | get_sdp_iterate (int *start, struct sip_request *req, const char *name) |
| Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number. | |
| static struct sip_pvt * | get_sip_pvt_byid_locked (const char *callid, const char *totag, const char *fromtag) |
Lock interface lock and find matching pvt lock
| |
| static const char * | gettag (const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize) |
| Get tag from packet. | |
| static int | handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v) |
| Handle flag-type options common to configuration of devices - users and peers. | |
| static int | handle_invite_replaces (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, struct sockaddr_in *sin) |
| Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. | |
| static int | handle_request (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock) |
| Handle incoming SIP requests (methods). | |
| static int | handle_request_bye (struct sip_pvt *p, struct sip_request *req) |
| Handle incoming BYE request. | |
| static int | handle_request_cancel (struct sip_pvt *p, struct sip_request *req) |
| Handle incoming CANCEL request. | |
| static void | handle_request_info (struct sip_pvt *p, struct sip_request *req) |
| Receive SIP INFO Message. | |
| static int | handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, char *e) |
| Handle incoming INVITE request. | |
| static int | handle_request_message (struct sip_pvt *p, struct sip_request *req) |
| Handle incoming MESSAGE request. | |
| static int | handle_request_notify (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e) |
| Handle incoming notifications. | |
| static int | handle_request_options (struct sip_pvt *p, struct sip_request *req) |
| Handle incoming OPTIONS request. | |
| static int | handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, int ignore, int seqno, int *nounlock) |
| static int | handle_request_register (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, char *e) |
| Handle incoming REGISTER request. | |
| static int | handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e) |
| Handle incoming SUBSCRIBE request. | |
| static void | handle_response (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
| Handle SIP response in dialogue. | |
| static void | handle_response_invite (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno) |
| Handle SIP response to INVITE dialogue. | |
| static void | handle_response_peerpoke (struct sip_pvt *p, int resp, struct sip_request *req) |
| Handle qualification responses (OPTIONS). | |
| static void | handle_response_refer (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno) |
| static int | handle_response_register (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) |
| Handle responses on REGISTER to services. | |
| static const char * | hangup_cause2sip (int cause) |
| Convert Asterisk hangup causes to SIP codes. | |
| static int | hangup_sip2cause (int cause) |
| Convert SIP hangup causes to Asterisk hangup causes. | |
| static int | init_req (struct sip_request *req, int sipmethod, const char *recip) |
| Initialize SIP request. | |
| static int | init_resp (struct sip_request *resp, const char *msg) |
| Initialize SIP response, based on SIP request. | |
| static void | initialize_initreq (struct sip_pvt *p, struct sip_request *req) |
| Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog. | |
| static void | initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod) |
| Initiate new SIP request to peer/user. | |
| static const char * | insecure2str (int port, int invite) |
| Convert Insecure setting to printable string. | |
| static void | list_route (struct sip_route *route) |
| List all routes - mostly for debugging. | |
| static int | load_module (void) |
| PBX load module - initialization. | |
| static int | local_attended_transfer (struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno) |
| Find all call legs and bridge transferee with target called from handle_request_refer. | |
| static int | lws2sws (char *msgbuf, int len) |
| Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled. | |
| static void | make_our_tag (char *tagbuf, size_t len) |
| Make our SIP dialog tag. | |
| static int | manager_sip_show_peer (struct mansession *s, const struct message *m) |
| Show SIP peers in the manager API. | |
| static int | manager_sip_show_peers (struct mansession *s, const struct message *m) |
| Show SIP peers in the manager API. | |
| static int | method_match (enum sipmethod id, const char *name) |
| returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send | |
| static char * | nat2str (int nat) |
| Convert NAT setting to text string. | |
| static void | parse_copy (struct sip_request *dst, const struct sip_request *src) |
| Copy SIP request, parse it. | |
| static void | parse_moved_contact (struct sip_pvt *p, struct sip_request *req) |
| Parse 302 Moved temporalily response. | |
| static int | parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req) |
| Save contact header for 200 OK on INVITE. | |
| static enum parse_register_result | parse_register_contact (struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req) |
| Parse contact header and save registration (peer registration). | |
| static void | parse_request (struct sip_request *req) |
| Parse a SIP message. | |
| static unsigned int | parse_sip_options (struct sip_pvt *pvt, const char *supported) |
| Parse supported header in incoming packet. | |
| static int | peer_status (struct sip_peer *peer, char *status, int statuslen) |
| Report Peer status in character string. | |
| static void | print_codec_to_cli (int fd, struct ast_codec_pref *pref) |
| Print codec list from preference to CLI/manager. | |
| static void | print_group (int fd, ast_group_t group, int crlf) |
| Print call group and pickup group. | |
| static int | process_sdp (struct sip_pvt *p, struct sip_request *req) |
| Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp(). | |
| static struct sip_peer * | realtime_peer (const char *newpeername, struct sockaddr_in *sin) |
| realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf | |
| static void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey) |
| Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups. | |
| static struct sip_user * | realtime_user (const char *username) |
| Load user from realtime storage Loads user from "sipusers" category in realtime (extconfig.conf) Users are matched on From: user name (the domain in skipped). | |
| static void | receive_message (struct sip_pvt *p, struct sip_request *req) |
| Receive SIP MESSAGE method messages. | |
| static char * | referstatus2str (enum referstatus rstatus) |
| Convert transfer status to string. | |
| static void | reg_source_db (struct sip_peer *peer) |
| Get registration details from Asterisk DB. | |
| static void | register_peer_exten (struct sip_peer *peer, int onoff) |
| Automatically add peer extension to dial plan. | |
| static enum check_auth_result | register_verify (struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri) |
Verify registration of user
| |
| static char * | regstate2str (enum sipregistrystate regstate) |
| Convert registration state status to string. | |
| static int | reload (void) |
| Part of Asterisk module interface. | |
| static int | reload_config (enum channelreloadreason reason) |
| Re-read SIP.conf config file. | |
| static int | reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len) |
| reply to authentication for outbound registrations | |
| static int | reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch) |
| Initialize a SIP request message (not the initial one in a dialog). | |
| static int | respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req) |
| Prepare SIP response packet. | |
| static int | restart_monitor (void) |
| Start the channel monitor thread. | |
| static int | retrans_pkt (void *data) |
| Retransmit SIP message if no answer (Called from scheduler). | |
| static int | send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
| Send SIP Request to the other part of the dialogue. | |
| static int | send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno) |
| Transmit response on SIP request. | |
| static int | set_address_from_contact (struct sip_pvt *pvt) |
| Change the other partys IP address based on given contact. | |
| static void | set_destination (struct sip_pvt *p, char *uri) |
| Set destination from SIP URI. | |
| static void | set_peer_defaults (struct sip_peer *peer) |
| Set peer defaults before configuring specific configurations. | |
| static int | sip_addheader (struct ast_channel *chan, void *data) |
| Add a SIP header to an outbound INVITE. | |
| static int | sip_addrcmp (char *name, struct sockaddr_in *sin) |
| Support routine for find_peer. | |
| static struct sip_pvt * | sip_alloc (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method) |
| Allocate SIP_PVT structure and set defaults. | |
| static void | sip_alreadygone (struct sip_pvt *dialog) |
| static int | sip_answer (struct ast_channel *ast) |
| sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface | |
| static int | sip_call (struct ast_channel *ast, char *dest, int timeout) |
| Initiate SIP call from PBX used from the dial() application. | |
| static void | sip_cancel_destroy (struct sip_pvt *p) |
| Cancel destruction of SIP dialog. | |
| static int | sip_debug_test_addr (const struct sockaddr_in *addr) |
| See if we pass debug IP filter. | |
| static int | sip_debug_test_pvt (struct sip_pvt *p) |
| Test PVT for debugging output. | |
| static void | sip_destroy (struct sip_pvt *p) |
| Destroy SIP call structure. | |
| static void | sip_destroy_peer (struct sip_peer *peer) |
| Destroy peer object from memory. | |
| static void | sip_destroy_user (struct sip_user *user) |
| Remove user object from in-memory storage. | |
| static int | sip_devicestate (void *data) |
| Part of PBX channel interface. | |
| static int | sip_do_debug (int fd, int argc, char *argv[]) |
| Turn on SIP debugging (CLI command). | |
| static int | sip_do_debug_deprecated (int fd, int argc, char *argv[]) |
| static int | sip_do_debug_ip (int fd, int argc, char *argv[]) |
| Enable SIP Debugging in CLI. | |
| static int | sip_do_debug_peer (int fd, int argc, char *argv[]) |
| sip_do_debug_peer: Turn on SIP debugging with peer mask | |
| static int | sip_do_history (int fd, int argc, char *argv[]) |
| Enable SIP History logging (CLI). | |
| static int | sip_do_reload (enum channelreloadreason reason) |
| Reload module. | |
| static int | sip_dtmfmode (struct ast_channel *chan, void *data) |
| Set the DTMFmode for an outbound SIP call (application). | |
| static void | sip_dump_history (struct sip_pvt *dialog) |
| Dump SIP history to debug log file at end of lifespan for SIP dialog. | |
| static int | sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
| sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links | |
| static int | sip_get_codec (struct ast_channel *chan) |
| Return SIP UA's codec (part of the RTP interface). | |
| static enum ast_rtp_get_result | sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
| Returns null if we can't reinvite audio (part of RTP interface). | |
| static struct ast_udptl * | sip_get_udptl_peer (struct ast_channel *chan) |
| static enum ast_rtp_get_result | sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
| Returns null if we can't reinvite video (part of RTP interface). | |
| static int | sip_handle_t38_reinvite (struct ast_channel *chan, struct sip_pvt *pvt, int reinvite) |
| Handle T38 reinvite. | |
| static int | sip_hangup (struct ast_channel *ast) |
| sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup | |
| static int | sip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen) |
| Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc. | |
| static const char * | sip_nat_mode (const struct sip_pvt *p) |
| Display SIP nat mode. | |
| static struct ast_channel * | sip_new (struct sip_pvt *i, int state, const char *title) |
| Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels. | |
| static int | sip_no_debug (int fd, int argc, char *argv[]) |
| Disable SIP Debugging in CLI. | |
| static int | sip_no_debug_deprecated (int fd, int argc, char *argv[]) |
| static int | sip_no_history (int fd, int argc, char *argv[]) |
| Disable SIP History logging (CLI). | |
| static int | sip_notify (int fd, int argc, char *argv[]) |
| Cli command to send SIP notify to peer. | |
| static int | sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno) |
| Park a call using the subsystem in res_features.c This is executed in a separate thread. | |
| static void * | sip_park_thread (void *stuff) |
| Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup. | |
| static void | sip_peer_hold (struct sip_pvt *p, int hold) |
| Change onhold state of a peer using a pvt structure. | |
| static void | sip_poke_all_peers (void) |
| Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions? | |
| static int | sip_poke_noanswer (void *data) |
| React to lack of answer to Qualify poke. | |
| static int | sip_poke_peer (struct sip_peer *peer) |
| Check availability of peer, also keep NAT open. | |
| static int | sip_poke_peer_s (void *data) |
| Poke peer (send qualify to check if peer is alive and well). | |
| static int | sip_prune_realtime (int fd, int argc, char *argv[]) |
| Remove temporary realtime objects from memory (CLI). | |
| static struct ast_frame * | sip_read (struct ast_channel *ast) |
| Read SIP RTP from channel. | |
| static struct sockaddr_in * | sip_real_dst (const struct sip_pvt *p) |
| The real destination address for a write. | |
| static int | sip_refer_allocate (struct sip_pvt *p) |
| Allocate SIP refer structure. | |
| static int | sip_reg_timeout (void *data) |
| Registration timeout, register again. | |
| static int | sip_register (char *value, int lineno) |
| Parse register=> line in sip.conf and add to registry. | |
| static void | sip_registry_destroy (struct sip_registry *reg) |
| Destroy registry object Objects created with the register= statement in static configuration. | |
| static int | sip_reload (int fd, int argc, char *argv[]) |
| Force reload of module from cli. | |
| static struct ast_channel * | sip_request_call (const char *type, int format, void *data, int *cause) |
| PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here. | |
| static int | sip_reregister (void *data) |
| Update registration with SIP Proxy. | |
| static struct ast_frame * | sip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect) |
| Read RTP from network. | |
| static void | sip_scheddestroy (struct sip_pvt *p, int ms) |
| Schedule destruction of SIP dialog. | |
| static void | sip_send_all_registers (void) |
| Send all known registrations. | |
| static int | sip_send_mwi_to_peer (struct sip_peer *peer) |
| Send message waiting indication to alert peer that they've got voicemail. | |
| static int | sip_senddigit_begin (struct ast_channel *ast, char digit) |
| static int | sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration) |
| Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously. | |
| static int | sip_sendtext (struct ast_channel *ast, const char *text) |
| Send SIP MESSAGE text within a call Called from PBX core sendtext() application. | |
| static int | sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active) |
| Set the RTP peer for this call. | |
| static int | sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl) |
| static int | sip_show_channel (int fd, int argc, char *argv[]) |
| Show details of one active dialog. | |
| static int | sip_show_channels (int fd, int argc, char *argv[]) |
| Show active SIP channels. | |
| static int | sip_show_domains (int fd, int argc, char *argv[]) |
| CLI command to list local domains. | |
| static int | sip_show_history (int fd, int argc, char *argv[]) |
| Show history details of one dialog. | |
| static int | sip_show_inuse (int fd, int argc, char *argv[]) |
| CLI Command to show calls within limits set by call_limit. | |
| static int | sip_show_objects (int fd, int argc, char *argv[]) |
| List all allocated SIP Objects (realtime or static). | |
| static int | sip_show_peer (int fd, int argc, char *argv[]) |
| Show one peer in detail. | |
| static int | sip_show_peers (int fd, int argc, char *argv[]) |
| CLI Show Peers command. | |
| static int | sip_show_registry (int fd, int argc, char *argv[]) |
| Show SIP Registry (registrations with other SIP proxies. | |
| static int | sip_show_settings (int fd, int argc, char *argv[]) |
| List global settings for the SIP channel. | |
| static int | sip_show_subscriptions (int fd, int argc, char *argv[]) |
| Show active SIP subscriptions. | |
| static int | sip_show_user (int fd, int argc, char *argv[]) |
| Show one user in detail. | |
| static int | sip_show_users (int fd, int argc, char *argv[]) |
| CLI Command 'SIP Show Users'. | |
| static int | sip_sipredirect (struct sip_pvt *p, const char *dest) |
| Transfer call before connect with a 302 redirect. | |
| static int | sip_transfer (struct ast_channel *ast, const char *dest) |
| Transfer SIP call. | |
| static int | sip_write (struct ast_channel *ast, struct ast_frame *frame) |
| Send frame to media channel (rtp). | |
| static int | sipsock_read (int *id, int fd, short events, void *ignore) |
| Read data from SIP socket. | |
| static void | stop_media_flows (struct sip_pvt *p) |
| Immediately stop RTP, VRTP and UDPTL as applicable. | |
| static const char * | subscription_type2str (enum subscriptiontype subtype) |
| Show subscription type in string format. | |
| static int | t38_get_rate (int t38cap) |
| Get Max T.38 Transmission rate from T38 capabilities. | |
| static struct sip_peer * | temp_peer (const char *name) |
| Create temporary peer (used in autocreatepeer mode). | |
| static void | temp_pvt_cleanup (void *) |
| static char * | transfermode2str (enum transfermodes mode) |
| Convert transfer mode to text string. | |
| static void | transmit_fake_auth_response (struct sip_pvt *p, struct sip_request *req, int reliable) |
| Send a fake 401 Unauthorized response when the administrator wants to hide the names of local users/peers from fishers. | |
| static int | transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration) |
| Send SIP INFO dtmf message, see Cisco documentation on cisco.com. | |
| static int | transmit_info_with_vidupdate (struct sip_pvt *p) |
| Send SIP INFO with video update request. | |
| static int | transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init) |
| Build REFER/INVITE/OPTIONS message and transmit it. | |
| static int | transmit_message_with_text (struct sip_pvt *p, const char *text) |
| Transmit text with SIP MESSAGE method. | |
| static int | transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten) |
| Notify user of messages waiting in voicemail. | |
| static int | transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate) |
| Notify a transferring party of the status of transfer. | |
| static int | transmit_refer (struct sip_pvt *p, const char *dest) |
| Transmit SIP REFER message (initiated by the transfer() dialplan application. | |
| static int | transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader) |
| Transmit register to SIP proxy or UA. | |
| static int | transmit_reinvite_with_sdp (struct sip_pvt *p) |
| Transmit reinvite with SDP. | |
| static int | transmit_reinvite_with_t38_sdp (struct sip_pvt *p) |
| Transmit reinvite with T38 SDP We reinvite so that the T38 processing can take place. SIP Signalling stays with * in the path. | |
| static int | transmit_request (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
| Transmit generic SIP request. | |
| static int | transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch) |
| Transmit SIP request, auth added. | |
| static int | transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
| Transmit response, no retransmits. | |
| static int | transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
| Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK. | |
| static int | transmit_response_using_temp (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg) |
| Transmit response, no retransmits, using a temporary pvt structure. | |
| static int | transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
| Append Accept header, content length before transmitting response. | |
| static int | transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale) |
| Respond with authorization request. | |
| static int | transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req) |
| Append date and content length before transmitting response. | |
| static int | transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable) |
| Used for 200 OK and 183 early media. | |
| static int | transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans) |
| Used for 200 OK and 183 early media. | |
| static int | transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported) |
| Transmit response, no retransmits. | |
| static int | transmit_sip_request (struct sip_pvt *p, struct sip_request *req) |
| Transmit SIP request unreliably (only used in sip_notify subsystem). | |
| static int | transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout) |
| Used in the SUBSCRIBE notification subsystem. | |
| static void | try_suggested_sip_codec (struct sip_pvt *p) |
| Try setting codec suggested by the SIP_CODEC channel variable. | |
| static int | unload_module (void) |
| PBX unload module API. | |
| static int | update_call_counter (struct sip_pvt *fup, int event) |
| update_call_counter: Handle call_limit for SIP users Setting a call-limit will cause calls above the limit not to be accepted. | |
| static void | update_peer (struct sip_peer *p, int expiry) |
| Update peer data in database (if used). | |
Variables | |
| static struct in_addr | __ourip |
| static int | allow_external_domains |
| static int | apeerobjs = 0 |
| static char * | app_dtmfmode = "SIPDtmfMode" |
| static char * | app_sipaddheader = "SIPAddHeader" |
| static struct sip_auth * | authl = NULL |
| static int | autocreatepeer |
| static struct sockaddr_in | bindaddr = { 0, } |
| static struct ast_custom_function | checksipdomain_function |
| static struct ast_cli_entry | cli_sip [] |
| static struct ast_cli_entry | cli_sip_debug_deprecated |
| static struct ast_cli_entry | cli_sip_no_debug_deprecated |
| static int | compactheaders |
| static const char | config [] = "sip.conf" |
| static char | debug_usage [] |
| static struct sockaddr_in | debugaddr |
| static char | default_callerid [AST_MAX_EXTENSION] |
| static char | default_context [AST_MAX_CONTEXT] |
| static int | default_expiry = DEFAULT_DEFAULT_EXPIRY |
| static char | default_fromdomain [AST_MAX_EXTENSION] |
| static struct ast_jb_conf | default_jbconf |
| Global jitterbuffer configuration - by default, jb is disabled. | |
| static char | default_language [MAX_LANGUAGE] |
| static int | default_maxcallbitrate |
| static char | default_mohinterpret [MAX_MUSICCLASS] |
| static char | default_mohsuggest [MAX_MUSICCLASS] |
| static char | default_notifymime [AST_MAX_EXTENSION] |
| static struct ast_codec_pref | default_prefs |
| static int | default_qualify |
| static char | default_subscribecontext [AST_MAX_CONTEXT] |
| static char | default_vmexten [AST_MAX_EXTENSION] |
| static char * | descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" |
| static char * | descrip_sipaddheader |
| static int | dumphistory |
| static int | expiry = DEFAULT_EXPIRY |
| static time_t | externexpire = 0 |
| static char | externhost [MAXHOSTNAMELEN] |
| static struct sockaddr_in | externip |
| static int | externrefresh = 10 |
| static int | global_allowguest |
| static int | global_allowsubscribe |
| static enum transfermodes | global_allowtransfer |
| static int | global_alwaysauthreject |
| static int | global_autoframing |
| static int | global_callevents |
| static int | global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 |
| Codecs that we support by default:. | |
| static int | global_directrtpsetup |
| static struct ast_flags | global_flags [2] = {{0}} |
| static struct ast_jb_conf | global_jbconf |
| static int | global_limitonpeers |
| static int | global_matchexterniplocally |
| static int | global_mwitime |
| static int | global_notifyhold |
| static int | global_notifyringing |
| static char | global_realm [MAXHOSTNAMELEN] |
| static int | global_reg_timeout |
| static int | global_regattempts_max |
| static char | global_regcontext [AST_MAX_CONTEXT] |
| static int | global_relaxdtmf |
| static int | global_rtautoclear |
| static int | global_rtpholdtimeout |
| static int | global_rtpkeepalive |
| static int | global_rtptimeout |
| static int | global_t1min |
| static int | global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 |
| static unsigned int | global_tos_audio |
| static unsigned int | global_tos_sip |
| static unsigned int | global_tos_video |
| static char | global_useragent [AST_MAX_EXTENSION] |
| static char | history_usage [] |
| static struct sip_pvt * | iflist |
| sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe | |
| static struct io_context * | io |
| static struct ast_ha * | localaddr |
| static char | mandescr_show_peer [] |
| static char | mandescr_show_peers [] |
| static int | max_expiry = DEFAULT_MAX_EXPIRY |
| static int | min_expiry = DEFAULT_MIN_EXPIRY |
| static pthread_t | monitor_thread = AST_PTHREADT_NULL |
| This is the thread for the monitor which checks for input on the channels which are not currently in use. | |
| static char | no_debug_usage [] |
| static char | no_history_usage [] |
| static const char | notify_config [] = "sip_notify.conf" |
| static struct ast_config * | notify_types |
| static char | notify_usage [] |
| static int | ourport |
| static struct sockaddr_in | outboundproxyip |
| static int | pedanticsipchecking |
| static struct ast_peer_list | peerl |
| The peer list: Peers and Friends. | |
| static char | prune_realtime_usage [] |
| static int | recordhistory |
| static struct c_referstatusstring | referstatusstrings [] |
| static struct ast_register_list | regl |
| The register list: Other SIP proxys we register with and place calls to. | |
| static int | regobjs = 0 |
| static int | rpeerobjs = 0 |
| static int | ruserobjs = 0 |
| static struct sched_context * | sched |
| static char | show_channel_usage [] |
| static char | show_channels_usage [] |
| static char | show_domains_usage [] |
| static char | show_history_usage [] |
| static char | show_inuse_usage [] |
| static char | show_objects_usage [] |
| static char | show_peer_usage [] |
| static char | show_peers_usage [] |
| static char | show_reg_usage [] |
| static char | show_settings_usage [] |
| static char | show_subscriptions_usage [] |
| static char | show_user_usage [] |
| static char | show_users_usage [] |
| static struct ast_custom_function | sip_header_function |
| static struct cfsip_methods | sip_methods [] |
| static struct cfsip_options | sip_options [] |
| List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. | |
| static char | sip_reload_usage [] |
| static int | sip_reloading = FALSE |
| static enum channelreloadreason | sip_reloadreason |
| static struct ast_rtp_protocol | sip_rtp |
| Interface structure with callbacks used to connect to RTP module. | |
| static struct ast_channel_tech | sip_tech |
| Definition of this channel for PBX channel registration. | |
| static struct ast_channel_tech | sip_tech_info |
| This version of the sip channel tech has no send_digit_begin callback. This is for use with channels using SIP INFO DTMF so that the core knows that the channel doesn't want DTMF BEGIN frames. | |
| static struct ast_udptl_protocol | sip_udptl |
| Interface structure with callbacks used to connect to UDPTL module. | |
| static struct ast_custom_function | sipchaninfo_function |
| Structure to declare a dialplan function: SIPCHANINFO. | |
| ast_custom_function | sippeer_function |
| Structure to declare a dialplan function: SIPPEER. | |
| static int | sipsock = -1 |
| static int * | sipsock_read_id |
| static int | speerobjs = 0 |
| static int | srvlookup |
| static struct cfsubscription_types | subscription_types [] |
| static int | suserobjs = 0 |
| static char * | synopsis_dtmfmode = "Change the dtmfmode for a SIP call" |
| static char * | synopsis_sipaddheader = "Add a SIP header to the outbound call" |
| static struct ast_user_list | userl |
| The user list: Users and friends. | |
See Also: Implementation of RFC 3261 - without S/MIME, TCP and TLS support Configuration file sip.conf
A new INVITE is sent to handle_request_invite(), that will end up starting a new channel in the PBX, the new channel after that executing in a separate channel thread. This is an incoming "call". When the call is answered, either by a bridged channel or the PBX itself the sip_answer() function is called.
The actual media - Video or Audio - is mostly handled by the RTP subsystem in rtp.c
Definition in file chan_sip.c.
| #define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY" |
SIP Methods we support.
Definition at line 464 of file chan_sip.c.
Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
| #define append_history | ( | p, | |||
| event, | |||||
| fmt, | |||||
| args... | ) | append_history_full(p, "%-15s " fmt, event, ## args) |
Append to SIP dialog history.
Definition at line 1810 of file chan_sip.c.
Referenced by __sip_autodestruct(), auto_congest(), build_reply_digest(), cb_extensionstate(), check_auth(), do_register_auth(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), local_attended_transfer(), process_sdp(), retrans_pkt(), send_request(), send_response(), sip_cancel_destroy(), sip_fixup(), sip_hangup(), sip_new(), sip_park_thread(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), sipsock_read(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_with_auth().
| #define CALLERID_UNKNOWN "Unknown" |
| #define CAN_CREATE_DIALOG 1 |
Definition at line 357 of file chan_sip.c.
| #define CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 2 |
Definition at line 358 of file chan_sip.c.
| #define CAN_NOT_CREATE_DIALOG 0 |
Definition at line 356 of file chan_sip.c.
| #define DEC_CALL_LIMIT 0 |
Definition at line 597 of file chan_sip.c.
Referenced by __sip_destroy(), handle_request_invite(), handle_response_invite(), sip_hangup(), and update_call_counter().
| #define DEC_CALL_RINGING 2 |
Definition at line 599 of file chan_sip.c.
Referenced by handle_response_invite(), and update_call_counter().
| #define DEFAULT_ALLOW_EXT_DOM TRUE |
| #define DEFAULT_ALLOWGUEST TRUE |
| #define DEFAULT_AUTOCREATEPEER FALSE |
| #define DEFAULT_CALLERID "asterisk" |
| #define DEFAULT_COMPACTHEADERS FALSE |
| #define DEFAULT_CONTEXT "default" |
| #define DEFAULT_DEFAULT_EXPIRY 120 |
Definition at line 164 of file chan_sip.c.
| #define DEFAULT_EXPIRY 900 |
Expire slowly
Definition at line 181 of file chan_sip.c.
| #define DEFAULT_FREQ_NOTOK 10 * 1000 |
Qualification: How often to check, if the host is down...
Definition at line 196 of file chan_sip.c.
| #define DEFAULT_FREQ_OK 60 * 1000 |
Qualification: How often to check for the host to be up
Definition at line 195 of file chan_sip.c.
| #define DEFAULT_MAX_CALL_BITRATE (384) |
| #define DEFAULT_MAX_EXPIRY 3600 |
Definition at line 166 of file chan_sip.c.
| #define DEFAULT_MAX_FORWARDS "70" |
Definition at line 168 of file chan_sip.c.
Referenced by initreqprep(), reqprep(), transmit_refer(), and transmit_register().
| #define DEFAULT_MAXMS 2000 |
Qualification: Must be faster than 2 seconds by default
Definition at line 194 of file chan_sip.c.
| #define DEFAULT_MIN_EXPIRY 60 |
Definition at line 165 of file chan_sip.c.
| #define DEFAULT_MOHINTERPRET "default" |
| #define DEFAULT_MOHSUGGEST "" |
| #define DEFAULT_MWITIME 10 |
| #define DEFAULT_NOTIFYMIME "application/simple-message-summary" |
| #define DEFAULT_NOTIFYRINGING TRUE |
| #define DEFAULT_PEDANTIC FALSE |
| #define DEFAULT_QUALIFY FALSE |
| #define DEFAULT_REALM "asterisk" |
| #define DEFAULT_REGISTRATION_TIMEOUT 20 |
| #define DEFAULT_RETRANS 1000 |
How frequently to retransmit Default: 2 * 500 ms in RFC 3261
Definition at line 198 of file chan_sip.c.
| #define DEFAULT_SRVLOOKUP FALSE |
| #define DEFAULT_T1MIN 100 |
100 MS for minimal roundtrip time
Definition at line 502 of file chan_sip.c.
Referenced by reload_config().
| #define DEFAULT_TOS_AUDIO 0 |
Audio packets should be marked as DSCP EF (Expedited Forwarding), but the default is 0 to be compatible with previous versions.
Definition at line 494 of file chan_sip.c.
Referenced by reload_config().
| #define DEFAULT_TOS_SIP 0 |
Call signalling packets should be marked as DSCP CS3, but the default is 0 to be compatible with previous versions.
Definition at line 493 of file chan_sip.c.
Referenced by reload_config().
| #define DEFAULT_TOS_VIDEO 0 |
Video packets should be marked as DSCP AF41, but the default is 0 to be compatible with previous versions.
Definition at line 495 of file chan_sip.c.
Referenced by reload_config().
| #define DEFAULT_TRANS_TIMEOUT -1 |
Definition at line 203 of file chan_sip.c.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), and sip_send_mwi_to_peer().
| #define DEFAULT_USERAGENT "Asterisk PBX" |
Default Useragent: header unless re-defined in sip.conf
Definition at line 505 of file chan_sip.c.
Referenced by reload_config().
| #define DEFAULT_VMEXTEN "asterisk" |
| #define EXPIRY_GUARD_LIMIT 30 |
Below here, we use EXPIRY_GUARD_PCT instead of EXPIRY_GUARD_SECS
Definition at line 173 of file chan_sip.c.
Referenced by handle_response_register().
| #define EXPIRY_GUARD_MIN 500 |
This is the minimum guard time applied. If GUARD_PCT turns out to be lower than this, it will use this time instead. This is in milliseconds.
Definition at line 175 of file chan_sip.c.
Referenced by handle_response_register().
| #define EXPIRY_GUARD_PCT 0.20 |
Percentage of expires timeout to use when below EXPIRY_GUARD_LIMIT
Definition at line 179 of file chan_sip.c.
Referenced by handle_response_register().
| #define EXPIRY_GUARD_SECS 15 |
How long before expiry do we reregister
Definition at line 172 of file chan_sip.c.
Referenced by handle_response_register().
| #define FALSE 0 |
Definition at line 150 of file chan_sip.c.
| #define FLAG_FATAL (1 << 1) |
| #define FLAG_RESPONSE (1 << 0) |
Definition at line 1006 of file chan_sip.c.
Referenced by __sip_ack(), __sip_pretend_ack(), __sip_reliable_xmit(), __sip_semi_ack(), handle_request(), and retrans_pkt().
| #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s %-10.10s\n" |
| #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" |
| #define FORMAT "%-40.40s %-20.20s %-16.16s\n" |
| #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" |
| #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" |
| #define FORMAT "%-25.25s %-15.15s %-15.15s \n" |
| #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-4.4s %-7.7s %-15.15s\n" |
| #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" |
| #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" |
| #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" |
| #define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" |
Referenced by __sip_show_channels().
| #define INC_CALL_LIMIT 1 |
Definition at line 598 of file chan_sip.c.
Referenced by handle_request_invite(), sip_hangup(), and update_call_counter().
| #define INC_CALL_RINGING 3 |
| #define INITIAL_CSEQ 101 |
our initial sip sequence number
Definition at line 210 of file chan_sip.c.
Referenced by sip_alloc(), sip_register(), and transmit_response_using_temp().
| #define IPTOS_MINCOST 0x02 |
Definition at line 159 of file chan_sip.c.
| #define MAX | ( | a, | |||
| b | ) | ((a) > (b) ? (a) : (b)) |
Definition at line 189 of file chan_sip.c.
| #define MAX_AUTHTRIES 3 |
Try authentication three times, then fail
Definition at line 204 of file chan_sip.c.
Referenced by handle_response(), handle_response_invite(), and handle_response_register().
| #define MAX_RETRANS 6 |
Try only 6 times for retransmissions, a total of 7 transmissions
Definition at line 199 of file chan_sip.c.
| #define NO_RTP 0 |
Definition at line 226 of file chan_sip.c.
| #define NOT_SUPPORTED 0 |
Definition at line 397 of file chan_sip.c.
| #define RTP 1 |
Definition at line 225 of file chan_sip.c.
| #define SDP_SAMPLE_RATE | ( | x | ) | (x == AST_FORMAT_G722) ? 16000 : 8000 |
| #define SIP_ALREADYGONE (1 << 0) |
Whether or not we've already been destroyed by our peer
Definition at line 704 of file chan_sip.c.
Referenced by handle_request(), handle_response_invite(), sip_alreadygone(), sip_hangup(), and sip_set_rtp_peer().
| #define SIP_CALL_LIMIT (1 << 28) |
Call limit enforced for this call
Definition at line 745 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), and update_call_counter().
| #define SIP_CAN_REINVITE (1 << 20) |
allow peers to be reinvited to send media directly p2p
Definition at line 733 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), reload_config(), sip_get_rtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), and sip_handle_t38_reinvite().
| #define SIP_CAN_REINVITE_NAT (2 << 20) |
allow media reinvite when new peer is behind NAT
Definition at line 734 of file chan_sip.c.
Referenced by handle_common_options(), sip_get_rtp_peer(), and sip_set_rtp_peer().
| #define SIP_DEFER_BYE_ON_TRANSFER (1 << 15) |
Do not hangup at first ast_hangup
Definition at line 719 of file chan_sip.c.
Referenced by handle_invite_replaces(), handle_request_refer(), local_attended_transfer(), and sip_hangup().
| #define SIP_DTMF (3 << 16) |
DTMF Support: four settings, uses two bits
Definition at line 720 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), create_addr_from_peer(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit_begin(), sip_senddigit_end(), sip_show_channel(), and sip_show_settings().
| #define SIP_DTMF_AUTO (3 << 16) |
DTMF Support: AUTO switch between rfc2833 and in-band DTMF
Definition at line 724 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), process_sdp(), and sip_alloc().
| #define SIP_DTMF_INBAND (1 << 16) |
DTMF Support: Inband audio, only for ULAW/ALAW - "inband"
Definition at line 722 of file chan_sip.c.
Referenced by dtmfmode2str(), handle_common_options(), process_sdp(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().
| #define SIP_DTMF_INFO (2 << 16) |
DTMF Support: SIP Info messages - "info"
Definition at line 723 of file chan_sip.c.
Referenced by dtmfmode2str(), handle_common_options(), sip_dtmfmode(), sip_new(), and sip_senddigit_end().
| #define SIP_DTMF_RFC2833 (0 << 16) |
DTMF Support: RTP DTMF - "rfc2833"
Definition at line 721 of file chan_sip.c.
Referenced by check_user_full(), create_addr_from_peer(), dtmfmode2str(), handle_common_options(), handle_request_invite(), process_sdp(), reload_config(), sip_alloc(), sip_dtmfmode(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().
| #define SIP_FLAGS_TO_COPY |
Value:
(SIP_PROMISCREDIR | SIP_TRUSTRPID | SIP_SENDRPID | SIP_DTMF | SIP_REINVITE | \ SIP_PROG_INBAND | SIP_USECLIENTCODE | SIP_NAT | SIP_G726_NONSTANDARD | \ SIP_USEREQPHONE | SIP_INSECURE_PORT | SIP_INSECURE_INVITE)
Definition at line 750 of file chan_sip.c.
Referenced by build_user(), check_user_full(), create_addr_from_peer(), set_peer_defaults(), sip_alloc(), and sip_poke_peer().
| #define SIP_FREE_BIT (1 << 14) |
----
Definition at line 718 of file chan_sip.c.
| #define SIP_G726_NONSTANDARD (1 << 31) |
Use non-standard packing for G726-32 data
Definition at line 748 of file chan_sip.c.
Referenced by add_codec_to_sdp(), handle_common_options(), and process_sdp().
| #define SIP_GOTREFER (1 << 7) |
Got a refer?
Definition at line 711 of file chan_sip.c.
Referenced by handle_request_refer(), local_attended_transfer(), sip_handle_t38_reinvite(), sip_read(), sip_set_rtp_peer(), and sip_set_udptl_peer().
| #define SIP_INC_COUNT (1 << 30) |
Did this connection increment the counter of in-use calls?
Definition at line 747 of file chan_sip.c.
Referenced by __sip_destroy(), sip_hangup(), and update_call_counter().
| #define SIP_INSECURE_INVITE (1 << 24) |
don't require authentication for incoming INVITEs
Definition at line 738 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), and handle_common_options().
| #define SIP_INSECURE_PORT (1 << 23) |
don't require matching port for incoming requests
Definition at line 737 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), and sip_addrcmp().
| #define SIP_MAX_HEADERS 64 |
Max amount of SIP headers to read
Definition at line 206 of file chan_sip.c.
Referenced by add_header(), and parse_request().
| #define SIP_MAX_LINES 64 |
Max amount of lines in SIP attachment (like SDP)
Definition at line 207 of file chan_sip.c.
Referenced by add_line(), and parse_request().
| #define SIP_MAX_PACKET 4096 |
Also from RFC 3261 (2543), should sub headers tho
Definition at line 208 of file chan_sip.c.
| #define SIP_NAT (3 << 18) |
four settings, uses two bits
Definition at line 726 of file chan_sip.c.
Referenced by _sip_show_peer(), build_via(), copy_via_headers(), create_addr_from_peer(), handle_common_options(), register_verify(), sip_alloc(), sip_nat_mode(), sip_real_dst(), sip_show_channel(), sip_show_settings(), sip_show_users(), and transmit_response_using_temp().
| #define SIP_NAT_ALWAYS (3 << 18) |
NAT Both ROUTE and RFC3581
Definition at line 730 of file chan_sip.c.
Referenced by copy_via_headers(), handle_common_options(), and nat2str().
| #define SIP_NAT_NEVER (0 << 18) |
No nat support
Definition at line 727 of file chan_sip.c.
Referenced by handle_common_options(), and nat2str().
| #define SIP_NAT_RFC3581 (1 << 18) |
NAT RFC3581
Definition at line 728 of file chan_sip.c.
Referenced by build_via(), copy_via_headers(), handle_common_options(), nat2str(), and reload_config().
| #define SIP_NAT_ROUTE (2 << 18) |
NAT Only ROUTE
Definition at line 729 of file chan_sip.c.
Referenced by _sip_show_peers(), check_user_full(), check_via(), create_addr_from_peer(), handle_common_options(), nat2str(), parse_register_contact(), send_request(), set_address_from_contact(), sip_alloc(), sip_nat_mode(), sip_real_dst(), and transmit_response_using_temp().
| #define SIP_NEEDDESTROY (1 << 1) |
if we need to be destroyed by the monitor thread
Definition at line 705 of file chan_sip.c.
Referenced by __sip_show_channels(), do_monitor(), handle_request(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), retrans_pkt(), sip_hangup(), sip_reg_timeout(), and sip_show_channel().
| #define SIP_NEEDREINVITE (1 << 5) |
Do we need to send another reinvite?
Definition at line 709 of file chan_sip.c.
Referenced by check_pendings(), sip_handle_t38_reinvite(), sip_hangup(), sip_read(), sip_set_rtp_peer(), and sip_set_udptl_peer().
| #define SIP_NO_HISTORY (1 << 27) |
Suppress recording request/response history
Definition at line 744 of file chan_sip.c.
Referenced by do_register_auth(), handle_request_bye(), handle_request_invite(), send_request(), send_response(), sip_alloc(), sip_hangup(), sip_new(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), sipsock_read(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_using_temp().
| #define SIP_NOVIDEO (1 << 2) |
Didn't get video in invite, don't offer
Definition at line 706 of file chan_sip.c.
Referenced by add_sdp(), process_sdp(), and sip_indicate().
| #define SIP_OPT_100REL (1 << 1) |
Definition at line 400 of file chan_sip.c.
| #define SIP_OPT_EARLY_SESSION (1 << 3) |
Definition at line 402 of file chan_sip.c.
| #define SIP_OPT_EVENTLIST (1 << 11) |
Definition at line 410 of file chan_sip.c.
| #define SIP_OPT_GRUU (1 << 12) |
Definition at line 411 of file chan_sip.c.
| #define SIP_OPT_HISTINFO (1 << 15) |
Definition at line 414 of file chan_sip.c.
| #define SIP_OPT_JOIN (1 << 4) |
Definition at line 403 of file chan_sip.c.
| #define SIP_OPT_NOREFERSUB (1 << 14) |
Definition at line 413 of file chan_sip.c.
| #define SIP_OPT_PATH (1 << 5) |
Definition at line 404 of file chan_sip.c.
| #define SIP_OPT_PRECONDITION (1 << 7) |
Definition at line 406 of file chan_sip.c.
| #define SIP_OPT_PREF (1 << 6) |
Definition at line 405 of file chan_sip.c.
| #define SIP_OPT_PRIVACY (1 << 8) |
Definition at line 407 of file chan_sip.c.
| #define SIP_OPT_REPLACES (1 << 0) |
| #define SIP_OPT_RESPRIORITY (1 << 16) |
Definition at line 415 of file chan_sip.c.
| #define SIP_OPT_SDP_ANAT (1 << 9) |
Definition at line 408 of file chan_sip.c.
| #define SIP_OPT_SEC_AGREE (1 << 10) |
Definition at line 409 of file chan_sip.c.
| #define SIP_OPT_TARGET_DIALOG (1 << 13) |
Definition at line 412 of file chan_sip.c.
| #define SIP_OPT_TIMER (1 << 2) |
Definition at line 401 of file chan_sip.c.
| #define SIP_OUTGOING (1 << 13) |
Direction of the last transaction in this dialog
Definition at line 717 of file chan_sip.c.
Referenced by get_sip_pvt_byid_locked(), handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), reqprep(), respprep(), sip_call(), sip_hangup(), sip_indicate(), sip_poke_peer(), sip_send_mwi_to_peer(), sip_show_channel(), sip_write(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_reinvite_with_t38_sdp(), and transmit_response_with_sdp().
| #define SIP_PAGE2_ALLOWOVERLAP (1 << 17) |
Allow overlap dialing ?
Definition at line 771 of file chan_sip.c.
Referenced by _sip_show_peer(), get_destination(), handle_common_options(), handle_request_invite(), reload_config(), and sip_show_settings().
| #define SIP_PAGE2_ALLOWSUBSCRIBE (1 << 16) |
Allow subscriptions from this peer?
Definition at line 770 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), handle_common_options(), handle_request_subscribe(), reload_config(), and sip_show_settings().
| #define SIP_PAGE2_BUGGY_MWI (1 << 26) |
26: Buggy CISCO MWI fix
Definition at line 782 of file chan_sip.c.
Referenced by handle_common_options(), and transmit_notify_with_mwi().
| #define SIP_PAGE2_CALL_ONHOLD (3 << 23) |
Call states
Definition at line 778 of file chan_sip.c.
Referenced by __sip_show_channels(), process_sdp(), and update_call_counter().
| #define SIP_PAGE2_CALL_ONHOLD_INACTIVE (1 << 24) |
| #define SIP_PAGE2_CALL_ONHOLD_ONEDIR (1 << 23) |
23: One directional hold
Definition at line 779 of file chan_sip.c.
Referenced by add_sdp(), and process_sdp().
| #define SIP_PAGE2_DEBUG (3 << 11) |
Definition at line 764 of file chan_sip.c.
| #define SIP_PAGE2_DEBUG_CONFIG (1 << 11) |
| #define SIP_PAGE2_DEBUG_CONSOLE (1 << 12) |
Definition at line 766 of file chan_sip.c.
Referenced by reload_config(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), and sip_no_debug_deprecated().
| #define SIP_PAGE2_DYNAMIC (1 << 13) |
Dynamic Peers register with Asterisk
Definition at line 767 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), function_sippeer(), register_verify(), and temp_peer().
| #define SIP_PAGE2_FLAGS_TO_COPY |
Value:
(SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_VIDEOSUPPORT | \ SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | SIP_PAGE2_BUGGY_MWI)
Definition at line 785 of file chan_sip.c.
Referenced by build_user(), check_user_full(), create_addr_from_peer(), set_peer_defaults(), sip_alloc(), and sip_poke_peer().
| #define SIP_PAGE2_IGNOREREGEXPIRE (1 << 10) |
Definition at line 763 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), and sip_show_settings().
| #define SIP_PAGE2_INC_RINGING (1 << 19) |
Did this connection increment the counter of in-use calls?
Definition at line 773 of file chan_sip.c.
Referenced by update_call_counter().
| #define SIP_PAGE2_OUTGOING_CALL (1 << 27) |
27: Is this an outgoing call?
Definition at line 783 of file chan_sip.c.
Referenced by sip_request_call(), and update_call_counter().
| #define SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) |
25: ????
Definition at line 781 of file chan_sip.c.
Referenced by create_addr_from_peer(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), and sip_show_settings().
| #define SIP_PAGE2_RT_FROMCONTACT (1 << 4) |
Definition at line 760 of file chan_sip.c.
Referenced by build_peer(), destroy_association(), parse_register_contact(), and reg_source_db().
| #define SIP_PAGE2_RTAUTOCLEAR (1 << 2) |
| #define SIP_PAGE2_RTCACHEFRIENDS (1 << 0) |
Definition at line 757 of file chan_sip.c.
Referenced by complete_sip_prune_realtime_peer(), complete_sip_prune_realtime_user(), sip_prune_realtime(), sip_show_settings(), and update_peer().
| #define SIP_PAGE2_RTSAVE_SYSNAME (1 << 5) |
Definition at line 761 of file chan_sip.c.
Referenced by realtime_update_peer(), and sip_show_settings().
| #define SIP_PAGE2_RTUPDATE (1 << 1) |
Definition at line 758 of file chan_sip.c.
Referenced by reload_config(), sip_show_settings(), and update_peer().
| #define SIP_PAGE2_SELFDESTRUCT (1 << 14) |
Automatic peers need to destruct themselves
Definition at line 768 of file chan_sip.c.
Referenced by expire_register(), sip_destroy_peer(), and temp_peer().
| #define SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 18) |
Only issue MWI notification if subscribed to
Definition at line 772 of file chan_sip.c.
Referenced by build_peer(), does_peer_need_mwi(), and register_verify().
| #define SIP_PAGE2_T38SUPPORT (7 << 20) |
T38 Fax Passthrough Support
Definition at line 774 of file chan_sip.c.
Referenced by create_addr_from_peer(), and sip_alloc().
| #define SIP_PAGE2_T38SUPPORT_RTP (2 << 20) |
21: T38 Fax Passthrough Support (not implemented)
Definition at line 776 of file chan_sip.c.
Referenced by _sip_show_peer(), add_sdp(), handle_common_options(), and sip_show_settings().
| #define SIP_PAGE2_T38SUPPORT_TCP (4 << 20) |
22: T38 Fax Passthrough Support (not implemented)
Definition at line 777 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), and sip_show_settings().
| #define SIP_PAGE2_T38SUPPORT_UDPTL (1 << 20) |
20: T38 Fax Passthrough Support
Definition at line 775 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), sip_read(), sip_rtp_read(), and sip_show_settings().
| #define SIP_PAGE2_VIDEOSUPPORT (1 << 15) |
Definition at line 769 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), check_user_full(), create_addr_from_peer(), handle_common_options(), reload_config(), sip_alloc(), and sip_show_settings().
| #define SIP_PENDINGBYE (1 << 6) |
Need to send bye after we ack?
Definition at line 710 of file chan_sip.c.
Referenced by check_pendings(), handle_response_invite(), sip_handle_t38_reinvite(), sip_hangup(), sip_read(), sip_set_rtp_peer(), and sip_set_udptl_peer().
| #define SIP_PKT_DEBUG (1 << 0) |
Debug this packet
Definition at line 790 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 792 of file chan_sip.c.
Referenced by check_user_full(), handle_request(), handle_request_bye(), handle_request_invite(), handle_request_message(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), and register_verify().
| #define SIP_PKT_IGNORE_REQ (1 << 4) |
| #define SIP_PKT_IGNORE_RESP (1 << 3) |
| #define SIP_PKT_WITH_TOTAG (1 << 1) |
This packet has a to-tag
Definition at line 791 of file chan_sip.c.
Referenced by find_call(), and handle_request().
| #define SIP_PROG_INBAND (3 << 25) |
three settings, uses two bits
Definition at line 740 of file chan_sip.c.
Referenced by handle_common_options(), sip_indicate(), and sip_show_settings().
| #define SIP_PROG_INBAND_NEVER (0 << 25) |
| #define SIP_PROG_INBAND_NO (1 << 25) |
Definition at line 742 of file chan_sip.c.
Referenced by handle_common_options(), and sip_show_settings().
| #define SIP_PROG_INBAND_YES (2 << 25) |
Definition at line 743 of file chan_sip.c.
Referenced by handle_common_options(), and sip_indicate().
| #define SIP_PROGRESS_SENT (1 << 4) |
Have sent 183 message progress
Definition at line 708 of file chan_sip.c.
Referenced by sip_indicate(), and sip_write().
| #define SIP_PROMISCREDIR (1 << 8) |
Promiscuous redirection
Definition at line 712 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), parse_moved_contact(), sip_show_channel(), and sip_show_settings().
| #define SIP_REALTIME (1 << 11) |
Flag for realtime users
Definition at line 715 of file chan_sip.c.
Referenced by _sip_show_peer(), _sip_show_peers(), build_peer(), parse_register_contact(), sip_destroy_peer(), sip_destroy_user(), and update_peer().
| #define SIP_REINVITE (7 << 20) |
| #define SIP_REINVITE_UPDATE (4 << 20) |
use UPDATE (RFC3311) when reinviting this peer
Definition at line 735 of file chan_sip.c.
Referenced by handle_common_options(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
| #define SIP_RINGING (1 << 3) |
| #define SIP_SENDRPID (1 << 29) |
Remote Party-ID Support
Definition at line 746 of file chan_sip.c.
Referenced by _sip_show_peer(), handle_common_options(), and initreqprep().
| #define SIP_TRANS_TIMEOUT 32000 |
SIP request timeout (rfc 3261) 64*T1
Definition at line 200 of file chan_sip.c.
Referenced by sip_call().
| #define SIP_TRUSTRPID (1 << 9) |
Trust RPID headers?
Definition at line 713 of file chan_sip.c.
Referenced by _sip_show_peer(), check_user_full(), and handle_common_options().
| #define SIP_USECLIENTCODE (1 << 12) |
Trust X-ClientCode info message
Definition at line 716 of file chan_sip.c.
Referenced by handle_common_options(), handle_request_info(), and sip_show_settings().
| #define SIP_USEREQPHONE (1 << 10) |
Add user=phone to numeric URI. Default off
Definition at line 714 of file chan_sip.c.
Referenced by _sip_show_peer(), build_peer(), initreqprep(), and sip_show_settings().
| #define sipdebug ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG) |
Definition at line 822 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 823 of file chan_sip.c.
| #define sipdebug_console ast_test_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE) |
Definition at line 824 of file chan_sip.c.
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
| #define STANDARD_SIP_PORT 5060 |
Standard SIP port from RFC 3261. DO NOT CHANGE THIS.
Definition at line 470 of file chan_sip.c.
Referenced by build_contact(), build_peer(), check_via(), create_addr(), initreqprep(), parse_register_contact(), reload_config(), set_address_from_contact(), set_destination(), set_peer_defaults(), sip_show_registry(), and transmit_register().
| #define SUPPORTED 1 |
Define SIP option tags, used in Require: and Supported: headers We need to be aware of these properties in the phones to use the replace: header. We should not do that without knowing that the other end supports it... This is nothing we can configure, we learn by the dialog Supported: header on the REGISTER (peer) or the INVITE (other devices) We are not using many of these today, but will in the future. This is documented in RFC 3261
Definition at line 396 of file chan_sip.c.
| #define SUPPORTED_EXTENSIONS "replaces" |
SIP Extensions we support.
Definition at line 467 of file chan_sip.c.
Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), and transmit_reinvite_with_t38_sdp().
| #define T38FAX_FILL_BIT_REMOVAL (1 << 0) |
Default: 0 (unset)
Definition at line 797 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 816 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 817 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 812 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 813 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 814 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 815 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 802 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
| #define T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF (0 << 3) |
Definition at line 801 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 799 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 798 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 805 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 804 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 806 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 808 of file chan_sip.c.
Referenced by add_t38_sdp().
| #define T38FAX_VERSION_0 (0 << 6) |
Version 0
Definition at line 809 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
| #define T38FAX_VERSION_1 (1 << 6) |
Version 1
Definition at line 810 of file chan_sip.c.
Referenced by add_t38_sdp(), and process_sdp().
| #define TRUE 1 |
Definition at line 154 of file chan_sip.c.
| #define UNLINK | ( | element, | |||
| head, | |||||
| prev | ) |
--- some list management macros.
Definition at line 1580 of file chan_sip.c.
Referenced by __sip_ack(), and __sip_destroy().
| #define VIDEO_CODEC_MASK 0x1fc0000 |
Video codecs from H.261 thru AST_FORMAT_MAX_VIDEO
Definition at line 157 of file chan_sip.c.
| enum check_auth_result |
Authentication result from check_auth* functions.
| AUTH_SUCCESSFUL | |
| AUTH_CHALLENGE_SENT | |
| AUTH_SECRET_FAILED | |
| AUTH_USERNAME_MISMATCH | |
| AUTH_NOT_FOUND | |
| AUTH_FAKE_AUTH | |
| AUTH_UNKNOWN_DOMAIN |
Definition at line 334 of file chan_sip.c.
00334 { 00335 AUTH_SUCCESSFUL = 0, 00336 AUTH_CHALLENGE_SENT = 1, 00337 AUTH_SECRET_FAILED = -1, 00338 AUTH_USERNAME_MISMATCH = -2, 00339 AUTH_NOT_FOUND = -3, 00340 AUTH_FAKE_AUTH = -4, 00341 AUTH_UNKNOWN_DOMAIN = -5, 00342 };
| enum domain_mode |
Modes for SIP domain handling in the PBX.
| SIP_DOMAIN_AUTO | This domain is auto-configured |
| SIP_DOMAIN_CONFIG | This domain is from configuration |
Definition at line 667 of file chan_sip.c.
00667 { 00668 SIP_DOMAIN_AUTO, /*!< This domain is auto-configured */ 00669 SIP_DOMAIN_CONFIG, /*!< This domain is from configuration */ 00670 };
| enum invitestates |
States for the INVITE transaction, not the dialog.
Definition at line 245 of file chan_sip.c.
00245 { 00246 INV_NONE = 0, /*!< No state at all, maybe not an INVITE dialog */ 00247 INV_CALLING = 1, /*!< Invite sent, no answer */ 00248 INV_PROCEEDING = 2, /*!< We got/sent 1xx message */ 00249 INV_EARLY_MEDIA = 3, /*!< We got 18x message with to-tag back */ 00250 INV_COMPLETED = 4, /*!< Got final response with error. Wait for ACK, then CONFIRMED */ 00251 INV_CONFIRMED = 5, /*!< Confirmed response - we've got an ack (Incoming calls only) */ 00252 INV_TERMINATED = 6, /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done 00253 The only way out of this is a BYE from one side */ 00254 INV_CANCELLED = 7, /*!< Transaction cancelled by client or server in non-terminated state */ 00255 };
Definition at line 272 of file chan_sip.c.
00272 { 00273 PARSE_REGISTER_FAILED, 00274 PARSE_REGISTER_UPDATE, 00275 PARSE_REGISTER_QUERY, 00276 };
| enum referstatus |
Parameters to know status of transfer.
Definition at line 846 of file chan_sip.c.
00846 { 00847 REFER_IDLE, /*!< No REFER is in progress */ 00848 REFER_SENT, /*!< Sent REFER to transferee */ 00849 REFER_RECEIVED, /*!< Received REFER from transferer */ 00850 REFER_CONFIRMED, /*!< Refer confirmed with a 100 TRYING */ 00851 REFER_ACCEPTED, /*!< Accepted by transferee */ 00852 REFER_RINGING, /*!< Target Ringing */ 00853 REFER_200OK, /*!< Answered by transfer target */ 00854 REFER_FAILED, /*!< REFER declined - go on */ 00855 REFER_NOAUTH /*!< We had no auth for REFER */ 00856 };
| enum sip_auth_type |
Authentication types - proxy or www authentication.
Definition at line 328 of file chan_sip.c.
00328 { 00329 PROXY_AUTH, 00330 WWW_AUTH, 00331 };
| enum sip_result |
Definition at line 237 of file chan_sip.c.
00237 { 00238 AST_SUCCESS = 0, 00239 AST_FAILURE = -1, 00240 };
| enum sipmethod |
SIP Request methods known by Asterisk.
| SIP_UNKNOWN | |
| SIP_RESPONSE | |
| SIP_REGISTER | |
| SIP_OPTIONS | |
| SIP_NOTIFY | |
| SIP_INVITE | |
| SIP_ACK | |
| SIP_PRACK | |
| SIP_BYE | |
| SIP_REFER | |
| SIP_SUBSCRIBE | |
| SIP_MESSAGE | |
| SIP_UPDATE | |
| SIP_INFO | |
| SIP_CANCEL | |
| SIP_PUBLISH | |
| SIP_PING |
Definition at line 303 of file chan_sip.c.
00303 { 00304 SIP_UNKNOWN, /* Unknown response */ 00305 SIP_RESPONSE, /* Not request, response to outbound request */ 00306 SIP_REGISTER, 00307 SIP_OPTIONS, 00308 SIP_NOTIFY, 00309 SIP_INVITE, 00310 SIP_ACK, 00311 SIP_PRACK, /* Not supported at all */ 00312 SIP_BYE, 00313 SIP_REFER, 00314 SIP_SUBSCRIBE, 00315 SIP_MESSAGE, 00316 SIP_UPDATE, /* We can send UPDATE; but not accept it */ 00317 SIP_INFO, 00318 SIP_CANCEL, 00319 SIP_PUBLISH, /* Not supported at all */ 00320 SIP_PING, /* Not supported at all, no standard but still implemented out there */ 00321 };
| enum sipregistrystate |
States for outbound registrations (with register= lines in sip.conf.
Definition at line 345 of file chan_sip.c.
00345 { 00346 REG_STATE_UNREGISTERED = 0, /*!< We are not registred */ 00347 REG_STATE_REGSENT, /*!< Registration request sent */ 00348 REG_STATE_AUTHSENT, /*!< We have tried to authenticate */ 00349 REG_STATE_REGISTERED, /*!< Registred and done */ 00350 REG_STATE_REJECTED, /*!< Registration rejected */ 00351 REG_STATE_TIMEOUT, /*!< Registration timed out */ 00352 REG_STATE_NOAUTH, /*!< We have no accepted credentials */ 00353 REG_STATE_FAILED, /*!< Registration failed after several tries */ 00354 };
| enum subscriptiontype |
Definition at line 278 of file chan_sip.c.
00278 { 00279 NONE = 0, 00280 XPIDF_XML, 00281 DIALOG_INFO_XML, 00282 CPIM_PIDF_XML, 00283 PIDF_XML, 00284 MWI_NOTIFICATION 00285 };
| enum t38state |
T38 States for a call.
Definition at line 827 of file chan_sip.c.
00827 { 00828 T38_DISABLED = 0, /*!< Not enabled */ 00829 T38_LOCAL_DIRECT, /*!< Offered from local */ 00830 T38_LOCAL_REINVITE, /*!< Offered from local - REINVITE */ 00831 T38_PEER_DIRECT, /*!< Offered from peer */ 00832 T38_PEER_REINVITE, /*!< Offered from peer - REINVITE */ 00833 T38_ENABLED /*!< Negotiated (enabled) */ 00834 };
| enum transfermodes |
Authorization scheme for call transfers.
Definition at line 231 of file chan_sip.c.
00231 { 00232 TRANSFER_OPENFORALL, /*!< Allow all SIP transfers */ 00233 TRANSFER_CLOSED, /*!< Allow no SIP transfers */ 00234 };
| enum xmittype |
Definition at line 265 of file chan_sip.c.
00265 { 00266 XMIT_CRITICAL = 2, /*!< Transmit critical SIP message reliably, with re-transmits. 00267 If it fails, it's critical and will cause a teardown of the session */ 00268 XMIT_RELIABLE = 1, /*!< Transmit SIP message reliably, with re-transmits */ 00269 XMIT_UNRELIABLE = 0, /*!< Transmit SIP message without bothering with re-transmits */ 00270 };
| static const char * __get_header | ( | const struct sip_request * | req, | |
| const char * | name, | |||
| int * | start | |||
| ) | [static] |
Definition at line 4006 of file chan_sip.c.
References find_alias(), sip_request::header, sip_request::headers, and len.
04007 { 04008 int pass; 04009 04010 /* 04011 * Technically you can place arbitrary whitespace both before and after the ':' in 04012 * a header, although RFC3261 clearly says you shouldn't before, and place just 04013 * one afterwards. If you shouldn't do it, what absolute idiot decided it was 04014 * a good idea to say you can do it, and if you can do it, why in the hell would. 04015 * you say you shouldn't. 04016 * Anyways, pedanticsipchecking controls whether we allow spaces before ':', 04017 * and we always allow spaces after that for compatibility. 04018 */ 04019 for (pass = 0; name && pass < 2;pass++) { 04020 int x, len = strlen(name); 04021 for (x=*start; x<req->headers; x++) { 04022 if (!strncasecmp(req->header[x], name, len)) { 04023 char *r = req->header[x] + len; /* skip name */ 04024 if (pedanticsipchecking) 04025 r = ast_skip_blanks(r); 04026 04027 if (*r == ':') { 04028 *start = x+1; 04029 return ast_skip_blanks(r+1); 04030 } 04031 } 04032 } 04033 if (pass == 0) /* Try aliases */ 04034 name = find_alias(name, NULL); 04035 } 04036 04037 /* Don't return NULL, so get_header is always a valid pointer */ 04038 return ""; 04039 }
| static void __sip_ack | ( | struct sip_pvt * | p, | |
| int | seqno, | |||
| int | resp, | |||
| int | sipmethod | |||
| ) | [static] |
Acknowledges receipt of a packet and stops retransmission.
Definition at line 2055 of file chan_sip.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_test_flag, sip_pkt::data, FALSE, FLAG_RESPONSE, free, sip_pvt::lock, LOG_DEBUG, sip_pkt::next, option_debug, sip_pvt::packets, sip_pvt::pendinginvite, sip_pkt::retransid, sched, sip_pkt::seqno, sip_methods, sipdebug, cfsip_methods::text, TRUE, and UNLINK.
Referenced by __sip_pretend_ack(), handle_request(), and handle_response().
02056 { 02057 struct sip_pkt *cur, *prev = NULL; 02058 02059 /* Just in case... */ 02060 char *msg; 02061 int res = FALSE; 02062 02063 msg = sip_methods[sipmethod].text; 02064 02065 ast_mutex_lock(&p->lock); 02066 for (cur = p->packets; cur; prev = cur, cur = cur->next) { 02067 if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) && 02068 ((ast_test_flag(cur, FLAG_RESPONSE)) || 02069 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) { 02070 if (!resp && (seqno == p->pendinginvite)) { 02071 if (option_debug) 02072 ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite); 02073 p->pendinginvite = 0; 02074 } 02075 /* this is our baby */ 02076 res = TRUE; 02077 UNLINK(cur, p->packets, prev); 02078 if (cur->retransid > -1) { 02079 if (sipdebug && option_debug > 3) 02080 ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid); 02081 ast_sched_del(sched, cur->retransid); 02082 cur->retransid = -1; 02083 } 02084 free(cur); 02085 break; 02086 } 02087 } 02088 ast_mutex_unlock(&p->lock); 02089 if (option_debug) 02090 ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found"); 02091 }
| static int __sip_autodestruct | ( | void * | data | ) | [static] |
Kill a SIP dialog (called by scheduler).
Definition at line 1989 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup(), ASTOBJ_UNREF, sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, LOG_DEBUG, LOG_WARNING, sip_pvt::method, NONE, option_debug, sip_pvt::owner, sip_pvt::refer, sip_pvt::relatedpeer, SIP_BYE, sip_destroy(), sip_destroy_peer(), sip_methods, sip_scheddestroy(), sip_pvt::subscribed, cfsip_methods::text, transmit_request_with_auth(), transmit_state_notify(), TRUE, and XMIT_RELIABLE.
Referenced by sip_scheddestroy().
01990 { 01991 struct sip_pvt *p = data; 01992 01993 /* If this is a subscription, tell the phone that we got a timeout */ 01994 if (p->subscribed) { 01995 transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE); /* Send last notification */ 01996 p->subscribed = NONE; 01997 append_history(p, "Subscribestatus", "timeout"); 01998 if (option_debug > 2) 01999 ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>"); 02000 return 10000; /* Reschedule this destruction so that we know that it's gone */ 02001 } 02002 02003 /* If we're destroying a subscription, dereference peer object too */ 02004 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 02005 ASTOBJ_UNREF(p->relatedpeer,sip_destroy_peer); 02006 02007 /* Reset schedule ID */ 02008 p->autokillid = -1; 02009 02010 if (option_debug) 02011 ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid); 02012 append_history(p, "AutoDestroy", "%s", p->callid); 02013 if (p->owner) { 02014 ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); 02015 ast_queue_hangup(p->owner); 02016 } else if (p->refer) { 02017 if (option_debug > 2) 02018 ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid); 02019 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 02020 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 02021 } else 02022 sip_destroy(p); 02023 return 0; 02024 }
| static void __sip_destroy | ( | struct sip_pvt * | p, | |
| int | lockowner | |||
| ) | [static] |
Execute destruction of SIP dialog structure, release memory.
Definition at line 2884 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_extension_state_del(), AST_LIST_REMOVE_HEAD, ast_log(), ast_rtp_destroy(), ast_sched_del(), ast_test_flag, ast_udptl_destroy(), ast_verbose(), ASTOBJ_UNREF, DEC_CALL_LIMIT, sip_pvt::flags, free, free_old_route(), iflist, LOG_DEBUG, LOG_WARNING, sip_pvt::method, sip_peer::mwipvt, sip_pvt::next, option_debug, sip_pvt::relatedpeer, sip_pkt::retransid, sched, sip_debug_test_pvt(), sip_dump_history(), SIP_INC_COUNT, sip_methods, sip_registry_destroy(), cfsip_methods::text, UNLINK, and update_call_counter().
Referenced by do_monitor(), sip_destroy(), and unload_module().
02885 { 02886 struct sip_pvt *cur, *prev = NULL; 02887 struct sip_pkt *cp; 02888 02889 if (sip_debug_test_pvt(p) || option_debug > 2) 02890 ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text); 02891 02892 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT)) { 02893 update_call_counter(p, DEC_CALL_LIMIT); 02894 if (option_debug > 1) 02895 ast_log(LOG_DEBUG, "This call did not properly clean up call limits. Call ID %s\n", p->callid); 02896 } 02897 02898 /* Remove link from peer to subscription of MWI */ 02899 if (p->relatedpeer && p->relatedpeer->mwipvt) 02900 p->relatedpeer->mwipvt = NULL; 02901 02902 if (dumphistory) 02903 sip_dump_history(p); 02904 02905 if (p->options) 02906 free(p->options); 02907 02908 if (p->stateid > -1) 02909 ast_extension_state_del(p->stateid, NULL); 02910 if (p->initid > -1) 02911 ast_sched_del(sched, p->initid); 02912 if (p->autokillid > -1) 02913 ast_sched_del(sched, p->autokillid); 02914 02915 if (p->rtp) 02916 ast_rtp_destroy(p->rtp); 02917 if (p->vrtp) 02918 ast_rtp_destroy(p->vrtp); 02919 if (p->udptl) 02920 ast_udptl_destroy(p->udptl); 02921 if (p->refer) 02922 free(p->refer); 02923 if (p->route) { 02924 free_old_route(p->route); 02925 p->route = NULL; 02926 } 02927 if (p->registry) { 02928 if (p->registry->call == p) 02929 p->registry->call = NULL; 02930 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 02931 } 02932 02933 /* Unlink us from the owner if we have one */ 02934 if (p->owner) { 02935 if (lockowner) 02936 ast_channel_lock(p->owner); 02937 if (option_debug) 02938 ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name); 02939 p->owner->tech_pvt = NULL; 02940 if (lockowner) 02941 ast_channel_unlock(p->owner); 02942 } 02943 /* Clear history */ 02944 if (p->history) { 02945 struct sip_history *hist; 02946 while( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) 02947 free(hist); 02948 free(p->history); 02949 p->history = NULL; 02950 } 02951 02952 for (prev = NULL, cur = iflist; cur; prev = cur, cur = cur->next) { 02953 if (cur == p) { 02954 UNLINK(cur, iflist, prev); 02955 break; 02956 } 02957 } 02958 if (!cur) { 02959 ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", p->callid); 02960 return; 02961 } 02962 02963 /* remove all current packets in this dialog */ 02964 while((cp = p->packets)) { 02965 p->packets = p->packets->next; 02966 if (cp->retransid > -1) 02967 ast_sched_del(sched, cp->retransid); 02968 free(cp); 02969 } 02970 if (p->chanvars) { 02971 ast_variables_destroy(p->chanvars); 02972 p->chanvars = NULL; 02973 } 02974 ast_mutex_destroy(&p->lock); 02975 02976 ast_string_field_free_pools(p); 02977 02978 free(p); 02979 }
| static int __sip_do_register | ( | struct sip_registry * | r | ) | [static] |
Register with SIP proxy.
Definition at line 7166 of file chan_sip.c.
References SIP_REGISTER, and transmit_register().
Referenced by sip_reregister().
07167 { 07168 int res; 07169 07170 res = transmit_register(r, SIP_REGISTER, NULL, NULL); 07171 return res; 07172 }
| static void __sip_pretend_ack | ( | struct sip_pvt * | p | ) | [static] |
Pretend to ack all packets maybe the lock on p is not strictly necessary but there might be a race.
Definition at line 2095 of file chan_sip.c.
References __sip_ack(), ast_log(), ast_test_flag, sip_pkt::data, find_sip_method(), FLAG_RESPONSE, LOG_WARNING, sip_pkt::method, sip_pvt::packets, sip_pkt::seqno, sip_methods, and cfsip_methods::text.
Referenced by sip_hangup(), and sip_reg_timeout().
02096 { 02097 struct sip_pkt *cur = NULL; 02098 02099 while (p->packets) { 02100 int method; 02101 if (cur == p->packets) { 02102 ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text); 02103 return; 02104 } 02105 cur = p->packets; 02106 method = (cur->method) ? cur->method : find_sip_method(cur->data); 02107 __sip_ack(p, cur->seqno, ast_test_flag(cur, FLAG_RESPONSE), method); 02108 } 02109 }
| 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 1951 of file chan_sip.c.
References __sip_xmit(), ast_calloc, AST_FAILURE, ast_log(), ast_sched_add_variable(), ast_set_flag, AST_SUCCESS, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, LOG_DEBUG, option_debug, sip_pkt::owner, sip_pvt::packets, sip_pvt::pendinginvite, retrans_pkt(), sched, SIP_INVITE, sipdebug, and sip_pvt::timer_t1.
Referenced by send_request(), and send_response().
01952 { 01953 struct sip_pkt *pkt; 01954 int siptimer_a = DEFAULT_RETRANS; 01955 01956 if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1))) 01957 return AST_FAILURE; 01958 memcpy(pkt->data, data, len); 01959 pkt->method = sipmethod; 01960 pkt->packetlen = len; 01961 pkt->next = p->packets; 01962 pkt->owner = p; 01963 pkt->seqno = seqno; 01964 if (resp) 01965 ast_set_flag(pkt, FLAG_RESPONSE); 01966 pkt->data[len] = '\0'; 01967 pkt->timer_t1 = p->timer_t1; /* Set SIP timer T1 */ 01968 if (fatal) 01969 ast_set_flag(pkt, FLAG_FATAL); 01970 if (pkt->timer_t1) 01971 siptimer_a = pkt->timer_t1 * 2; 01972 01973 /* Schedule retransmission */ 01974 pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1); 01975 if (option_debug > 3 && sipdebug) 01976 ast_log(LOG_DEBUG, "*** SIP TIMER: Initalizing retransmit timer on packet: Id #%d\n", pkt->retransid); 01977 pkt->next = p->packets; 01978 p->packets = pkt; 01979 01980 __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); /* Send packet */ 01981 if (sipmethod == SIP_INVITE) { 01982 /* Note this is a pending invite */ 01983 p->pendinginvite = seqno; 01984 } 01985 return AST_SUCCESS; 01986 }
| 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 2112 of file chan_sip.c.
References ast_log(), ast_sched_del(), ast_test_flag, sip_pkt::data, FLAG_RESPONSE, LOG_DEBUG, method_match(), sip_pkt::next, option_debug, sip_pvt::packets, sip_pkt::retransid, sched, sip_pkt::seqno, sip_methods, sipdebug, and cfsip_methods::text.
Referenced by handle_response().
02113 { 02114 struct sip_pkt *cur; 02115 int res = -1; 02116 02117 for (cur = p->packets; cur; cur = cur->next) { 02118 if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp && 02119 (ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) { 02120 /* this is our baby */ 02121 if (cur->retransid > -1) { 02122 if (option_debug > 3 && sipdebug) 02123 ast_log(LOG_DEBUG, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text); 02124 ast_sched_del(sched, cur->retransid); 02125 cur->retransid = -1; 02126 } 02127 res = 0; 02128 break; 02129 } 02130 } 02131 if (option_debug) 02132 ast_log(LOG_DEBUG, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found"); 02133 return res; 02134 }
| static int __sip_show_channels | ( | int | fd, | |
| int | argc, | |||
| char * | argv[], | |||
| int | subscriptions | |||
| ) | [static] |
SIP show channels CLI (main function).
Definition at line 10447 of file chan_sip.c.
References ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_test_flag, sip_pvt::flags, FORMAT, FORMAT2, FORMAT3, sip_pvt::icseq, iflist, sip_pvt::lastmsg, ast_channel::nativeformats, sip_pvt::next, NONE, sip_pvt::ocseq, sip_pvt::owner, sip_pvt::refer, referstatus2str(), RESULT_SHOWUSAGE, S_OR, sip_pvt::sa, SIP_NEEDDESTROY, SIP_PAGE2_CALL_ONHOLD, sip_refer::status, and sip_pvt::subscribed.
Referenced by sip_show_channels(), and sip_show_subscriptions().
10448 { 10449 #define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n" 10450 #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-4.4s %-7.7s %-15.15s\n" 10451 #define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s %-10.10s\n" 10452 struct sip_pvt *cur; 10453 int numchans = 0; 10454 char *referstatus = NULL; 10455 10456 if (argc != 3) 10457 return RESULT_SHOWUSAGE; 10458 ast_mutex_lock(&iflock); 10459 cur = iflist; 10460 if (!subscriptions) 10461 ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message"); 10462 else 10463 ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox"); 10464 for (; cur; cur = cur->next) { 10465 referstatus = ""; 10466 if (cur->refer) { /* SIP transfer in progress */ 10467 referstatus = referstatus2str(cur->refer->status); 10468 } 10469 if (cur->subscribed == NONE && !subscriptions) { 10470 ast_cli(fd, FORMAT, ast_inet_ntoa(cur->sa.sin_addr), 10471 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10472 cur->callid, 10473 cur->ocseq, cur->icseq, 10474 ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), 10475 ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD) ? "Yes" : "No", 10476 ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "", 10477 cur->lastmsg , 10478 referstatus 10479 ); 10480 numchans++; 10481 } 10482 if (cur->subscribed != NONE && subscriptions) { 10483 ast_cli(fd, FORMAT3, ast_inet_ntoa(cur->sa.sin_addr), 10484 S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 10485 cur->callid, 10486 /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */ 10487 cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri, 10488 cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 10489 subscription_type2str(cur->subscribed), 10490 cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>" 10491 ); 10492 numchans++; 10493 } 10494 } 10495 ast_mutex_unlock(&iflock); 10496 if (!subscriptions) 10497 ast_cli(fd, "%d active SIP channel%s\n", numchans, (numchans != 1) ? "s" : ""); 10498 else 10499 ast_cli(fd, "%d active SIP subscription%s\n", numchans, (numchans != 1) ? "s" : ""); 10500 return RESULT_SUCCESS; 10501 #undef FORMAT 10502 #undef FORMAT2 10503 #undef FORMAT3 10504 }
| static int __sip_xmit | ( | struct sip_pvt * | p, | |
| char * | data, | |||
| int | len | |||
| ) | [static] |
Transmit SIP message.
Definition at line 1747 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), LOG_WARNING, sip_real_dst(), and sipsock.
Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response().
01748 { 01749 int res; 01750 const struct sockaddr_in *dst = sip_real_dst(p); 01751 res = sendto(sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in)); 01752 01753 if (res != len) 01754 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)); 01755 return res; 01756 }
| 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 5737 of file chan_sip.c.
References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), get_header(), ast_channel::hangupcause, LOG_WARNING, sip_pvt::method, sip_pvt::owner, respprep(), send_response(), and SIP_INVITE.
Referenced by transmit_response(), transmit_response_reliable(), and transmit_response_using_temp().
05738 { 05739 struct sip_request resp; 05740 int seqno = 0; 05741 05742 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 05743 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 05744 return -1; 05745 } 05746 respprep(&resp, p, msg, req); 05747 add_header_contentLength(&resp, 0); 05748 /* If we are cancelling an incoming invite for some reason, add information 05749 about the reason why we are doing this in clear text */ 05750 if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) { 05751 char buf[10]; 05752 05753 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 05754 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 05755 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 05756 } 05757 return send_response(p, &resp, reliable, seqno); 05758 }
| 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 9999 of file chan_sip.c.
References sip_peer::accountcode, sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_check_realtime(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_print_group(), ast_sched_when(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, dtmfmode2str(), sip_peer::expire, FALSE, find_peer(), sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_peer::ha, insecure2str(), sip_peer::language, sip_peer::lastmsg, sip_peer::lastmsgssent, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_auth::md5secret, sip_peer::md5secret, ast_variable::name, nat2str(), ast_variable::next, sip_auth::next, peer_status(), sip_peer::pickupgroup, sip_peer::prefs, print_codec_to_cli(), print_group(), sip_auth::realm, sip_peer::regexten, RESULT_SHOWUSAGE, RESULT_SUCCESS, s, S_OR, sched, sip_auth::secret, sip_peer::secret, SIP_CAN_REINVITE, sip_destroy_peer(), SIP_DTMF, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, sip_options, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROMISCREDIR, SIP_REALTIME, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USEREQPHONE, sip_peer::sipoptions, sip_peer::subscribecontext, text, sip_peer::tohost, transfermode2str(), TRUE, sip_peer::useragent, sip_peer::username, sip_auth::username, ast_variable::value, and sip_peer::vmexten.
Referenced by manager_sip_show_peer(), and sip_show_peer().
10000 { 10001 char status[30] = ""; 10002 char cbuf[256]; 10003 struct sip_peer *peer; 10004 char codec_buf[512]; 10005 struct ast_codec_pref *pref; 10006 struct ast_variable *v; 10007 struct sip_auth *auth; 10008 int x = 0, codec = 0, load_realtime; 10009 int realtimepeers; 10010 10011 realtimepeers = ast_check_realtime("sippeers"); 10012 10013 if (argc < 4) 10014 return RESULT_SHOWUSAGE; 10015 10016 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10017 peer = find_peer(argv[3], NULL, load_realtime); 10018 if (s) { /* Manager */ 10019 if (peer) { 10020 const char *id = astman_get_header(m,"ActionID"); 10021 10022 astman_append(s, "Response: Success\r\n"); 10023 if (!ast_strlen_zero(id)) 10024 astman_append(s, "ActionID: %s\r\n",id); 10025 } else { 10026 snprintf (cbuf, sizeof(cbuf), "Peer %s not found.\n", argv[3]); 10027 astman_send_error(s, m, cbuf); 10028 return 0; 10029 } 10030 } 10031 if (peer && type==0 ) { /* Normal listing */ 10032 ast_cli(fd,"\n\n"); 10033 ast_cli(fd, " * Name : %s\n", peer->name); 10034 if (realtimepeers) { /* Realtime is enabled */ 10035 ast_cli(fd, " Realtime peer: %s\n", ast_test_flag(&peer->flags[0], SIP_REALTIME) ? "Yes, cached" : "No"); 10036 } 10037 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 10038 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); 10039 for (auth = peer->auth; auth; auth = auth->next) { 10040 ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); 10041 ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>")); 10042 } 10043 ast_cli(fd, " Context : %s\n", peer->context); 10044 ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); 10045 ast_cli(fd, " Language : %s\n", peer->language); 10046 if (!ast_strlen_zero(peer->accountcode)) 10047 ast_cli(fd, " Accountcode : %s\n", peer->accountcode); 10048 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(peer->amaflags)); 10049 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(peer->allowtransfer)); 10050 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(peer->callingpres)); 10051 if (!ast_strlen_zero(peer->fromuser)) 10052 ast_cli(fd, " FromUser : %s\n", peer->fromuser); 10053 if (!ast_strlen_zero(peer->fromdomain)) 10054 ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); 10055 ast_cli(fd, " Callgroup : "); 10056 print_group(fd, peer->callgroup, 0); 10057 ast_cli(fd, " Pickupgroup : "); 10058 print_group(fd, peer->pickupgroup, 0); 10059 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 10060 ast_cli(fd, " VM Extension : %s\n", peer->vmexten); 10061 ast_cli(fd, " LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff); 10062 ast_cli(fd, " Call limit : %d\n", peer->call_limit); 10063 ast_cli(fd, " Dynamic : %s\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Yes":"No")); 10064 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 10065 ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate); 10066 ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire)); 10067 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))); 10068 ast_cli(fd, " Nat : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10069 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 10070 ast_cli(fd, " T38 pt UDPTL : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_UDPTL)?"Yes":"No"); 10071 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10072 ast_cli(fd, " T38 pt RTP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_RTP)?"Yes":"No"); 10073 ast_cli(fd, " T38 pt TCP : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT_TCP)?"Yes":"No"); 10074 #endif 10075 ast_cli(fd, " CanReinvite : %s\n", ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Yes":"No"); 10076 ast_cli(fd, " PromiscRedir : %s\n", ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Yes":"No"); 10077 ast_cli(fd, " User=Phone : %s\n", ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Yes":"No"); 10078 ast_cli(fd, " Video Support: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"); 10079 ast_cli(fd, " Trust RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_TRUSTRPID) ? "Yes" : "No"); 10080 ast_cli(fd, " Send RPID : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No"); 10081 ast_cli(fd, " Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10082 ast_cli(fd, " Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10083 10084 /* - is enumerated */ 10085 ast_cli(fd, " DTMFmode : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10086 ast_cli(fd, " LastMsg : %d\n", peer->lastmsg); 10087 ast_cli(fd, " ToHost : %s\n", peer->tohost); 10088 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)); 10089 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 10090 if (!ast_strlen_zero(global_regcontext)) 10091 ast_cli(fd, " Reg. exten : %s\n", peer->regexten); 10092 ast_cli(fd, " Def. Username: %s\n", peer->username); 10093 ast_cli(fd, " SIP Options : "); 10094 if (peer->sipoptions) { 10095 int lastoption = -1; 10096 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10097 if (sip_options[x].id != lastoption) { 10098 if (peer->sipoptions & sip_options[x].id) 10099 ast_cli(fd, "%s ", sip_options[x].text); 10100 lastoption = x; 10101 } 10102 } 10103 } else 10104 ast_cli(fd, "(none)"); 10105 10106 ast_cli(fd, "\n"); 10107 ast_cli(fd, " Codecs : "); 10108 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10109 ast_cli(fd, "%s\n", codec_buf); 10110 ast_cli(fd, " Codec Order : ("); 10111 print_codec_to_cli(fd, &peer->prefs); 10112 ast_cli(fd, ")\n"); 10113 10114 ast_cli(fd, " Auto-Framing: %s \n", peer->autoframing ? "Yes" : "No"); 10115 ast_cli(fd, " Status : "); 10116 peer_status(peer, status, sizeof(status)); 10117 ast_cli(fd, "%s\n",status); 10118 ast_cli(fd, " Useragent : %s\n", peer->useragent); 10119 ast_cli(fd, " Reg. Contact : %s\n", peer->fullcontact); 10120 if (peer->chanvars) { 10121 ast_cli(fd, " Variables :\n"); 10122 for (v = peer->chanvars ; v ; v = v->next) 10123 ast_cli(fd, " %s = %s\n", v->name, v->value); 10124 } 10125 ast_cli(fd,"\n"); 10126 ASTOBJ_UNREF(peer,sip_destroy_peer); 10127 } else if (peer && type == 1) { /* manager listing */ 10128 char buf[256]; 10129 astman_append(s, "Channeltype: SIP\r\n"); 10130 astman_append(s, "ObjectName: %s\r\n", peer->name); 10131 astman_append(s, "ChanObjectType: peer\r\n"); 10132 astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y"); 10133 astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y"); 10134 astman_append(s, "Context: %s\r\n", peer->context); 10135 astman_append(s, "Language: %s\r\n", peer->language); 10136 if (!ast_strlen_zero(peer->accountcode)) 10137 astman_append(s, "Accountcode: %s\r\n", peer->accountcode); 10138 astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags)); 10139 astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres)); 10140 if (!ast_strlen_zero(peer->fromuser)) 10141 astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser); 10142 if (!ast_strlen_zero(peer->fromdomain)) 10143 astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain); 10144 astman_append(s, "Callgroup: "); 10145 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->callgroup)); 10146 astman_append(s, "Pickupgroup: "); 10147 astman_append(s, "%s\r\n", ast_print_group(buf, sizeof(buf), peer->pickupgroup)); 10148 astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox); 10149 astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer)); 10150 astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent); 10151 astman_append(s, "Call-limit: %d\r\n", peer->call_limit); 10152 astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate); 10153 astman_append(s, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)?"Y":"N")); 10154 astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "")); 10155 astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire)); 10156 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))); 10157 astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT))); 10158 astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N")); 10159 astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N")); 10160 astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N")); 10161 astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N")); 10162 astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N")); 10163 10164 /* - is enumerated */ 10165 astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF))); 10166 astman_append(s, "SIPLastMsg: %d\r\n", peer->lastmsg); 10167 astman_append(s, "ToHost: %s\r\n", peer->tohost); 10168 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)); 10169 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)); 10170 astman_append(s, "Default-Username: %s\r\n", peer->username); 10171 if (!ast_strlen_zero(global_regcontext)) 10172 astman_append(s, "RegExtension: %s\r\n", peer->regexten); 10173 astman_append(s, "Codecs: "); 10174 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 10175 astman_append(s, "%s\r\n", codec_buf); 10176 astman_append(s, "CodecOrder: "); 10177 pref = &peer->prefs; 10178 for(x = 0; x < 32 ; x++) { 10179 codec = ast_codec_pref_index(pref,x); 10180 if (!codec) 10181 break; 10182 astman_append(s, "%s", ast_getformatname(codec)); 10183 if (x < 31 && ast_codec_pref_index(pref,x+1)) 10184 astman_append(s, ","); 10185 } 10186 10187 astman_append(s, "\r\n"); 10188 astman_append(s, "Status: "); 10189 peer_status(peer, status, sizeof(status)); 10190 astman_append(s, "%s\r\n", status); 10191 astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent); 10192 astman_append(s, "Reg-Contact : %s\r\n", peer->fullcontact); 10193 if (peer->chanvars) { 10194 for (v = peer->chanvars ; v ; v = v->next) { 10195 astman_append(s, "ChanVariable:\n"); 10196 astman_append(s, " %s,%s\r\n", v->name, v->value); 10197 } 10198 } 10199 10200 ASTOBJ_UNREF(peer,sip_destroy_peer); 10201 10202 } else { 10203 ast_cli(fd,"Peer %s not found.\n", argv[3]); 10204 ast_cli(fd,"\n"); 10205 } 10206 10207 return RESULT_SUCCESS; 10208 }
| 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 9549 of file chan_sip.c.
References ast_check_realtime(), ast_cli(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, FORMAT2, id, name, peer_status(), peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, s, SIP_NAT_ROUTE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_VIDEOSUPPORT, SIP_REALTIME, and TRUE.
Referenced by manager_sip_show_peers(), and sip_show_peers().
09550 { 09551 regex_t regexbuf; 09552 int havepattern = FALSE; 09553 09554 #define FORMAT2 "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %-10s\n" 09555 #define FORMAT "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %-10s\n" 09556 09557 char name[256]; 09558 int total_peers = 0; 09559 int peers_mon_online = 0; 09560 int peers_mon_offline = 0; 09561 int peers_unmon_offline = 0; 09562 int peers_unmon_online = 0; 09563 const char *id; 09564 char idtext[256] = ""; 09565 int realtimepeers; 09566 09567 realtimepeers = ast_check_realtime("sippeers"); 09568 09569 if (s) { /* Manager - get ActionID */ 09570 id = astman_get_header(m,"ActionID"); 09571 if (!ast_strlen_zero(id)) 09572 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 09573 } 09574 09575 switch (argc) { 09576 case 5: 09577 if (!strcasecmp(argv[3], "like")) { 09578 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 09579 return RESULT_SHOWUSAGE; 09580 havepattern = TRUE; 09581 } else 09582 return RESULT_SHOWUSAGE; 09583 case 3: 09584 break; 09585 default: 09586 return RESULT_SHOWUSAGE; 09587 } 09588 09589 if (!s) /* Normal list */ 09590 ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : "")); 09591 09592 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09593 char status[20] = ""; 09594 char srch[2000]; 09595 char pstatus; 09596 09597 ASTOBJ_RDLOCK(iterator); 09598 09599 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09600 ASTOBJ_UNLOCK(iterator); 09601 continue; 09602 } 09603 09604 if (!ast_strlen_zero(iterator->username) && !s) 09605 snprintf(name, sizeof(name), "%s/%s", iterator->name, iterator->username); 09606 else 09607 ast_copy_string(name, iterator->name, sizeof(name)); 09608 09609 pstatus = peer_status(iterator, status, sizeof(status)); 09610 if (pstatus == 1) 09611 peers_mon_online++; 09612 else if (pstatus == 0) 09613 peers_mon_offline++; 09614 else { 09615 if (iterator->addr.sin_port == 0) 09616 peers_unmon_offline++; 09617 else 09618 peers_unmon_online++; 09619 } 09620 09621 snprintf(srch, sizeof(srch), FORMAT, name, 09622 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 09623 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 09624 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 09625 iterator->ha ? " A " : " ", /* permit/deny */ 09626 ntohs(iterator->addr.sin_port), status, 09627 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 09628 09629 if (!s) {/* Normal CLI list */ 09630 ast_cli(fd, FORMAT, name, 09631 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "(Unspecified)", 09632 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? " D " : " ", /* Dynamic or not? */ 09633 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? " N " : " ", /* NAT=yes? */ 09634 iterator->ha ? " A " : " ", /* permit/deny */ 09635 09636 ntohs(iterator->addr.sin_port), status, 09637 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "Cached RT":"") : ""); 09638 } else { /* Manager format */ 09639 /* The names here need to be the same as other channels */ 09640 astman_append(s, 09641 "Event: PeerEntry\r\n%s" 09642 "Channeltype: SIP\r\n" 09643 "ObjectName: %s\r\n" 09644 "ChanObjectType: peer\r\n" /* "peer" or "user" */ 09645 "IPaddress: %s\r\n" 09646 "IPport: %d\r\n" 09647 "Dynamic: %s\r\n" 09648 "Natsupport: %s\r\n" 09649 "VideoSupport: %s\r\n" 09650 "ACL: %s\r\n" 09651 "Status: %s\r\n" 09652 "RealtimeDevice: %s\r\n\r\n", 09653 idtext, 09654 iterator->name, 09655 iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iterator->addr.sin_addr) : "-none-", 09656 ntohs(iterator->addr.sin_port), 09657 ast_test_flag(&iterator->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no", /* Dynamic or not? */ 09658 ast_test_flag(&iterator->flags[0], SIP_NAT_ROUTE) ? "yes" : "no", /* NAT=yes? */ 09659 ast_test_flag(&iterator->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no", /* VIDEOSUPPORT=yes? */ 09660 iterator->ha ? "yes" : "no", /* permit/deny */ 09661 status, 09662 realtimepeers ? (ast_test_flag(&iterator->flags[0], SIP_REALTIME) ? "yes":"no") : "no"); 09663 } 09664 09665 ASTOBJ_UNLOCK(iterator); 09666 09667 total_peers++; 09668 } while(0) ); 09669 09670 if (!s) 09671 ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n", 09672 total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline); 09673 09674 if (havepattern) 09675 regfree(®exbuf); 09676 09677 if (total) 09678 *total = total_peers; 09679 09680 09681 return RESULT_SUCCESS; 09682 #undef FORMAT 09683 #undef FORMAT2 09684 }
| static int acf_channel_read | ( | struct ast_channel * | chan, | |
| char * | funcname, | |||
| char * | preparse, | |||
| char * | buf, | |||
| size_t | buflen | |||
| ) | [static] |
Definition at line 14159 of file chan_sip.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), ast_rtp_get_quality(), AST_STANDARD_APP_ARGS, ast_strdupa, LOG_ERROR, LOG_WARNING, parse(), sip_pvt::rtp, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, type, and sip_pvt::vrtp.
14160 { 14161 struct ast_rtp_quality qos; 14162 struct sip_pvt *p = chan->tech_pvt; 14163 char *all = "", *parse = ast_strdupa(preparse); 14164 AST_DECLARE_APP_ARGS(args, 14165 AST_APP_ARG(param); 14166 AST_APP_ARG(type); 14167 AST_APP_ARG(field); 14168 ); 14169 AST_STANDARD_APP_ARGS(args, parse); 14170 14171 /* Sanity check */ 14172 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 14173 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 14174 return 0; 14175 } 14176 14177 if (strcasecmp(args.param, "rtpqos")) 14178 return 0; 14179 14180 memset(buf, 0, buflen); 14181 memset(&qos, 0, sizeof(qos)); 14182 14183 if (strcasecmp(args.type, "AUDIO") == 0) { 14184 all = ast_rtp_get_quality(p->rtp, &qos); 14185 } else if (strcasecmp(args.type, "VIDEO") == 0) { 14186 all = ast_rtp_get_quality(p->vrtp, &qos); 14187 } 14188 14189 if (strcasecmp(args.field, "local_ssrc") == 0) 14190 snprintf(buf, buflen, "%u", qos.local_ssrc); 14191 else if (strcasecmp(args.field, "local_lostpackets") == 0) 14192 snprintf(buf, buflen, "%u", qos.local_lostpackets); 14193 else if (strcasecmp(args.field, "local_jitter") == 0) 14194 snprintf(buf, buflen, "%.0lf", qos.local_jitter * 1000.0); 14195 else if (strcasecmp(args.field, "local_count") == 0) 14196 snprintf(buf, buflen, "%u", qos.local_count); 14197 else if (strcasecmp(args.field, "remote_ssrc") == 0) 14198 snprintf(buf, buflen, "%u", qos.remote_ssrc); 14199 else if (strcasecmp(args.field, "remote_lostpackets") == 0) 14200 snprintf(buf, buflen, "%u", qos.remote_lostpackets); 14201 else if (strcasecmp(args.field, "remote_jitter") == 0) 14202 snprintf(buf, buflen, "%.0lf", qos.remote_jitter * 1000.0); 14203 else if (strcasecmp(args.field, "remote_count") == 0) 14204 snprintf(buf, buflen, "%u", qos.remote_count); 14205 else if (strcasecmp(args.field, "rtt") == 0) 14206 snprintf(buf, buflen, "%.0lf", qos.rtt * 1000.0); 14207 else if (strcasecmp(args.field, "all") == 0) 14208 ast_copy_string(buf, all, buflen); 14209 else { 14210 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 14211 return -1; 14212 } 14213 return 0; 14214 }
| static void add_blank | ( | struct sip_request * | req | ) | [static] |
add a blank line if no body
Definition at line 2147 of file chan_sip.c.
References sip_request::data, sip_request::len, and sip_request::lines.
Referenced by send_request(), and send_response().
02148 { 02149 if (!req->lines) { 02150 /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */ 02151 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 02152 req->len += strlen(req->data + req->len); 02153 } 02154 }
| 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 5941 of file chan_sip.c.
References ast_build_string(), ast_codec_pref_getsize(), AST_FORMAT_G729A, AST_FORMAT_ILBC, ast_getformatname(), ast_rtp_codec_getpref(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), AST_RTP_OPT_G726_NONSTANDARD, ast_test_flag, ast_verbose(), sip_pvt::flags, fmt, sip_pvt::rtp, and SIP_G726_NONSTANDARD.
Referenced by add_sdp().
05944 { 05945 int rtp_code; 05946 struct ast_format_list fmt; 05947 05948 05949 if (debug) 05950 ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec)); 05951 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1) 05952 return; 05953 05954 if (p->rtp) { 05955 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 05956 fmt = ast_codec_pref_getsize(pref, codec); 05957 } 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 */ 05958 return; 05959 ast_build_string(m_buf, m_size, " %d", rtp_code); 05960 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 05961 ast_rtp_lookup_mime_subtype(1, codec, 05962 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0), 05963 sample_rate); 05964 if (codec == AST_FORMAT_G729A) { 05965 /* Indicate that we don't support VAD (G.729 annex B) */ 05966 ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code); 05967 } else if (codec == AST_FORMAT_ILBC) { 05968 /* Add information about us using only 20/30 ms packetization */ 05969 ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms); 05970 } 05971 05972 if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size)) 05973 *min_packet_size = fmt.cur_ms; 05974 05975 /* Our first codec packetization processed cannot be less than zero */ 05976 if ((*min_packet_size) == 0 && fmt.cur_ms) 05977 *min_packet_size = fmt.cur_ms; 05978 }
| static int add_digit | ( | struct sip_request * | req, | |
| char | digit, | |||
| unsigned int | duration | |||
| ) | [static] |
Add DTMF INFO tone to sip message.
Definition at line 5909 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_digit().
05910 { 05911 char tmp[256]; 05912 05913 snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration); 05914 add_header(req, "Content-Type", "application/dtmf-relay"); 05915 add_header_contentLength(req, strlen(tmp)); 05916 add_line(req, tmp); 05917 return 0; 05918 }
| static int add_header | ( | struct sip_request * | req, | |
| const char * | var, | |||
| const char * | value | |||
| ) | [static] |
Add header to SIP message.
Definition at line 5300 of file chan_sip.c.
References ast_log(), sip_request::data, find_alias(), sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, LOG_WARNING, and SIP_MAX_HEADERS.
05301 { 05302 int maxlen = sizeof(req->data) - 4 - req->len; /* 4 bytes are for two \r\n ? */ 05303 05304 if (req->headers == SIP_MAX_HEADERS) { 05305 ast_log(LOG_WARNING, "Out of SIP header space\n"); 05306 return -1; 05307 } 05308 05309 if (req->lines) { 05310 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 05311 return -1; 05312 } 05313 05314 if (maxlen <= 0) { 05315 ast_log(LOG_WARNING, "Out of space, can't add anymore (%s:%s)\n", var, value); 05316 return -1; 05317 } 05318 05319 req->header[req->headers] = req->data + req->len; 05320 05321 if (compactheaders) 05322 var = find_alias(var, var); 05323 05324 snprintf(req->header[req->headers], maxlen, "%s: %s\r\n", var, value); 05325 req->len += strlen(req->header[req->headers]); 05326 req->headers++; 05327 if (req->headers < SIP_MAX_HEADERS) 05328 req->headers++; 05329 else 05330 ast_log(LOG_WARNING, "Out of SIP header space... Will generate broken SIP message\n"); 05331 05332 return 0; 05333 }
| static int add_header_contentLength | ( | struct sip_request * | req, | |
| int | len | |||
| ) | [static] |
Add 'Content-Length' header to SIP message.
Definition at line 5336 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().
05337 { 05338 char clen[10]; 05339 05340 snprintf(clen, sizeof(clen), "%d", len); 05341 return add_header(req, "Content-Length", clen); 05342 }
| static int add_line | ( | struct sip_request * | req, | |
| const char * | line | |||
| ) | [static] |
Add content (not header) to SIP message.
Definition at line 5345 of file chan_sip.c.
References ast_log(), sip_request::data, sip_request::len, sip_request::line, sip_request::lines, LOG_WARNING, and SIP_MAX_LINES.
05346 { 05347 if (req->lines == SIP_MAX_LINES) { 05348 ast_log(LOG_WARNING, "Out of SIP line space\n"); 05349 return -1; 05350 } 05351 if (!req->lines) { 05352 /* Add extra empty return */ 05353 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 05354 req->len += strlen(req->data + req->len); 05355 } 05356 if (req->len >= sizeof(req->data) - 4) { 05357 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 05358 return -1; 05359 } 05360 req->line[req->lines] = req->data + req->len; 05361 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 05362 req->len += strlen(req->line[req->lines]); 05363 req->lines++; 05364 return 0; 05365 }
| 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 6114 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().
06117 { 06118 int rtp_code; 06119 06120 if (debug) 06121 ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0)); 06122 if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1) 06123 return; 06124 06125 ast_build_string(m_buf, m_size, " %d", rtp_code); 06126 ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code, 06127 ast_rtp_lookup_mime_subtype(0, format, 0), 06128 sample_rate); 06129 if (format == AST_RTP_DTMF) 06130 /* Indicate we support DTMF and FLASH... */ 06131 ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code); 06132 }
| static struct sip_auth * add_realm_authentication | ( | struct sip_auth * | authlist, | |
| char * | configuration, | |||
| int | lineno | |||
| ) | [static] |
Add realm authentication in list.
Definition at line 15680 of file chan_sip.c.
References ast_calloc, ast_log(), ast_strlen_zero(), ast_verbose(), LOG_DEBUG, LOG_WARNING, sip_auth::md5secret, sip_auth::next, option_debug, option_verbose, sip_auth::realm, secret, strsep(), and username.
Referenced by build_peer().
15681 { 15682 char authcopy[256]; 15683 char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; 15684 char *stringp; 15685 struct sip_auth *a, *b, *auth; 15686 15687 if (ast_strlen_zero(configuration)) 15688 return authlist; 15689 15690 if (option_debug) 15691 ast_log(LOG_DEBUG, "Auth config :: %s\n", configuration); 15692 15693 ast_copy_string(authcopy, configuration, sizeof(authcopy)); 15694 stringp = authcopy; 15695 15696 username = stringp; 15697 realm = strrchr(stringp, '@'); 15698 if (realm) 15699 *realm++ = '\0'; 15700 if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { 15701 ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); 15702 return authlist; 15703 } 15704 stringp = username; 15705 username = strsep(&stringp, ":"); 15706 if (username) { 15707 secret = strsep(&stringp, ":"); 15708 if (!secret) { 15709 stringp = username; 15710 md5secret = strsep(&stringp,"#"); 15711 } 15712 } 15713 if (!(auth = ast_calloc(1, sizeof(*auth)))) 15714 return authlist; 15715 15716 ast_copy_string(auth->realm, realm, sizeof(auth->realm)); 15717 ast_copy_string(auth->username, username, sizeof(auth->username)); 15718 if (secret) 15719 ast_copy_string(auth->secret, secret, sizeof(auth->secret)); 15720 if (md5secret) 15721 ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); 15722 15723 /* find the end of the list */ 15724 for (b = NULL, a = authlist; a ; b = a, a = a->next) 15725 ; 15726 if (b) 15727 b->next = auth; /* Add structure add end of list */ 15728 else 15729 authlist = auth; 15730 15731 if (option_verbose > 2) 15732 ast_verbose("Added authentication for realm %s\n", realm); 15733 15734 return authlist; 15735 15736 }
| static void add_route | ( | struct sip_request * | req, | |
| struct sip_route * | route | |||
| ) | [static] |
Add route header into request per learned route.
Definition at line 5466 of file chan_sip.c.
References add_header(), sip_route::hop, and sip_route::next.
Referenced by reqprep().
05467 { 05468 char r[BUFSIZ*2], *p; 05469 int n, rem = sizeof(r); 05470 05471 if (!route) 05472 return; 05473 05474 p = r; 05475 for (;route ; route = route->next) { 05476 n = strlen(route->hop); 05477 if (rem < n+3) /* we need room for ",<route>" */ 05478 break; 05479 if (p != r) { /* add a separator after fist route */ 05480 *p++ = ','; 05481 --rem; 05482 } 05483 *p++ = '<'; 05484 ast_copy_string(p, route->hop, rem); /* cannot fail */ 05485 p += n; 05486 *p++ = '>'; 05487 rem -= (n+2); 05488 } 05489 *p = '\0'; 05490 add_header(req, "Route", r); 05491 }
| static enum sip_result add_sdp | ( | struct sip_request * | resp, | |
| struct sip_pvt * | p | |||
| ) | [static] |
Add Session Description Protocol message.
Definition at line 6137 of file chan_sip.c.
References add_codec_to_sdp(), add_header(), add_header_contentLength(), add_line(), add_noncodec_to_sdp(), ast_build_string(), ast_codec_pref_index(), AST_FAILURE, AST_FORMAT_AUDIO_MASK, AST_FORMAT_MAX_AUDIO, AST_FORMAT_MAX_VIDEO, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_inet_ntoa(), ast_internal_timing_enabled(), ast_log(), ast_rtp_get_us(), AST_RTP_MAX, AST_SUCCESS, ast_test_flag, ast_verbose(), capability, debug, FALSE, sip_pvt::flags, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len, LOG_DEBUG, LOG_WARNING, sip_pvt::maxcallbitrate, option_debug, sip_pvt::ourip, sip_pvt::owner, sip_pvt::prefcodec, sip_pvt::prefs, sip_pvt::redirip, sip_pvt::rtp, SDP_SAMPLE_RATE, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, SIP_PAGE2_T38SUPPORT_RTP, sip_pvt::t38, t38properties::t38support, TRUE, sip_pvt::vredirip, and sip_pvt::vrtp.
06138 { 06139 int len = 0; 06140 int alreadysent = 0; 06141 06142 struct sockaddr_in sin; 06143 struct sockaddr_in vsin; 06144 struct sockaddr_in dest; 06145 struct sockaddr_in vdest = { 0, }; 06146 06147 /* SDP fields */ 06148 char *version = "v=0\r\n"; /* Protocol version */ 06149 char *subject = "s=session\r\n"; /* Subject of the session */ 06150 char owner[256]; /* Session owner/creator */ 06151 char connection[256]; /* Connection data */ 06152 char *stime = "t=0 0\r\n"; /* Time the session is active */ 06153 char bandwidth[256] = ""; /* Max bitrate */ 06154 char *hold; 06155 char m_audio[256]; /* Media declaration line for audio */ 06156 char m_video[256]; /* Media declaration line for video */ 06157 char a_audio[1024]; /* Attributes for audio */ 06158 char a_video[1024]; /* Attributes for video */ 06159 char *m_audio_next = m_audio; 06160 char *m_video_next = m_video; 06161 size_t m_audio_left = sizeof(m_audio); 06162 size_t m_video_left = sizeof(m_video); 06163 char *a_audio_next = a_audio; 06164 char *a_video_next = a_video; 06165 size_t a_audio_left = sizeof(a_audio); 06166 size_t a_video_left = sizeof(a_video); 06167 06168 int x; 06169 int capability; 06170 int needvideo = FALSE; 06171 int debug = sip_debug_test_pvt(p); 06172 int min_audio_packet_size = 0; 06173 int min_video_packet_size = 0; 06174 06175 m_video[0] = '\0'; /* Reset the video media string if it's not needed */ 06176 06177 if (!p->rtp) { 06178 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 06179 return AST_FAILURE; 06180 } 06181 06182 /* Set RTP Session ID and version */ 06183 if (!p->sessionid) { 06184 p->sessionid = getpid(); 06185 p->sessionversion = p->sessionid; 06186 } else 06187 p->sessionversion++; 06188 06189 /* Get our addresses */ 06190 ast_rtp_get_us(p->rtp, &sin); 06191 if (p->vrtp) 06192 ast_rtp_get_us(p->vrtp, &vsin); 06193 06194 /* Is this a re-invite to move the media out, then use the original offer from caller */ 06195 if (p->redirip.sin_addr.s_addr) { 06196 dest.sin_port = p->redirip.sin_port; 06197 dest.sin_addr = p->redirip.sin_addr; 06198 } else { 06199 dest.sin_addr = p->ourip; 06200 dest.sin_port = sin.sin_port; 06201 } 06202 06203 capability = p->jointcapability; 06204 06205 06206 if (option_debug > 1) { 06207 char codecbuf[BUFSIZ]; 06208 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"); 06209 ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec)); 06210 } 06211 06212 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 06213 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) { 06214 ast_build_string(&m_audio_next, &m_audio_left, " %d", 191); 06215 ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000); 06216 } 06217 #endif 06218 06219 /* Check if we need video in this call */ 06220 if ((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 06221 if (p->vrtp) { 06222 needvideo = TRUE; 06223 if (option_debug > 1) 06224 ast_log(LOG_DEBUG, "This call needs video offers!\n"); 06225 } else if (option_debug > 1) 06226 ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled!\n"); 06227 } 06228 06229 06230 /* Ok, we need video. Let's add what we need for video and set codecs. 06231 Video is handled differently than audio since we can not transcode. */ 06232 if (needvideo) { 06233 /* Determine video destination */ 06234 if (p->vredirip.sin_addr.s_addr) { 06235 vdest.sin_addr = p->vredirip.sin_addr; 06236 vdest.sin_port = p->vredirip.sin_port; 06237 } else { 06238 vdest.sin_addr = p->ourip; 06239 vdest.sin_port = vsin.sin_port; 06240 } 06241 ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port)); 06242 06243 /* Build max bitrate string */ 06244 if (p->maxcallbitrate) 06245 snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate); 06246 if (debug) 06247 ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port)); 06248 } 06249 06250 if (debug) 06251 ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 06252 06253 /* Start building generic SDP headers */ 06254 06255 /* We break with the "recommendation" and send our IP, in order that our 06256 peer doesn't have to ast_gethostbyname() us */ 06257 06258 snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr)); 06259 snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr)); 06260 ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 06261 06262 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR)) 06263 hold = "a=recvonly\r\n"; 06264 else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE)) 06265 hold = "a=inactive\r\n"; 06266 else 06267 hold = "a=sendrecv\r\n"; 06268 06269 /* Now, start adding audio codecs. These are added in this order: 06270 - First what was requested by the calling channel 06271 - Then preferences in order from sip.conf device config for this peer/user 06272 - Then other codecs in capabilities, including video 06273 */ 06274 06275 /* Prefer the audio codec we were requested to use, first, no matter what 06276 Note that p->prefcodec can include video codecs, so mask them out 06277 */ 06278 if (capability & p->prefcodec) { 06279 int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK; 06280 06281 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06282 &m_audio_next, &m_audio_left, 06283 &a_audio_next, &a_audio_left, 06284 debug, &min_audio_packet_size); 06285 alreadysent |= codec; 06286 } 06287 06288 /* Start by sending our preferred audio codecs */ 06289 for (x = 0; x < 32; x++) { 06290 int codec; 06291 06292 if (!(codec = ast_codec_pref_index(&p->prefs, x))) 06293 break; 06294 06295 if (!(capability & codec)) 06296 continue; 06297 06298 if (alreadysent & codec) 06299 continue; 06300 06301 add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec), 06302 &m_audio_next, &m_audio_left, 06303 &a_audio_next, &a_audio_left, 06304 debug, &min_audio_packet_size); 06305 alreadysent |= codec; 06306 } 06307 06308 /* Now send any other common audio and video codecs, and non-codec formats: */ 06309 for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) { 06310 if (!(capability & x)) /* Codec not requested */ 06311 continue; 06312 06313 if (alreadysent & x) /* Already added to SDP */ 06314 continue; 06315 06316 if (x <= AST_FORMAT_MAX_AUDIO) 06317 add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x), 06318 &m_audio_next, &m_audio_left, 06319 &a_audio_next, &a_audio_left, 06320 debug, &min_audio_packet_size); 06321 else 06322 add_codec_to_sdp(p, x, 90000, 06323 &m_video_next, &m_video_left, 06324 &a_video_next, &a_video_left, 06325 debug, &min_video_packet_size); 06326 } 06327 06328 /* Now add DTMF RFC2833 telephony-event as a codec */ 06329 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 06330 if (!(p->jointnoncodeccapability & x)) 06331 continue; 06332 06333 add_noncodec_to_sdp(p, x, 8000, 06334 &m_audio_next, &m_audio_left, 06335 &a_audio_next, &a_audio_left, 06336 debug); 06337 } 06338 06339 if (option_debug > 2) 06340 ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n"); 06341 06342 if (!p->owner || !ast_internal_timing_enabled(p->owner)) 06343 ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n"); 06344 06345 if (min_audio_packet_size) 06346 ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size); 06347 06348 if (min_video_packet_size) 06349 ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size); 06350 06351 if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0)) 06352 ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n"); 06353 06354 ast_build_string(&m_audio_next, &m_audio_left, "\r\n"); 06355 if (needvideo) 06356 ast_build_string(&m_video_next, &m_video_left, "\r\n"); 06357 06358 len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold); 06359 if (needvideo) /* only if video response is appropriate */ 06360 len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold); 06361 06362 add_header(resp, "Content-Type", "application/sdp"); 06363 add_header_contentLength(resp, len); 06364 add_line(resp, version); 06365 add_line(resp, owner); 06366 add_line(resp, subject); 06367 add_line(resp, connection); 06368 if (needvideo) /* only if video response is appropriate */ 06369 add_line(resp, bandwidth); 06370 add_line(resp, stime); 06371 add_line(resp, m_audio); 06372 add_line(resp, a_audio); 06373 add_line(resp, hold); 06374 if (needvideo) { /* only if video response is appropriate */ 06375 add_line(resp, m_video); 06376 add_line(resp, a_video); 06377 add_line(resp, hold); /* Repeat hold for the video stream */ 06378 } 06379 06380 /* Update lastrtprx when we send our SDP */ 06381 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 06382 06383 if (option_debug > 2) { 06384 char buf[BUFSIZ]; 06385 ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, BUFSIZ, capability)); 06386 } 06387 06388 return AST_SUCCESS; 06389 }
| 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 15616 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), LOG_DEBUG, LOG_WARNING, and sipdebug.
15617 { 15618 struct domain *d; 15619 15620 if (ast_strlen_zero(domain)) { 15621 ast_log(LOG_WARNING, "Zero length domain.\n"); 15622 return 1; 15623 } 15624 15625 if (!(d = ast_calloc(1, sizeof(*d)))) 15626 return 0; 15627 15628 ast_copy_string(d->domain, domain, sizeof(d->domain)); 15629 15630 if (!ast_strlen_zero(context)) 15631 ast_copy_string(d->context, context, sizeof(d->context)); 15632 15633 d->mode = mode; 15634 15635 AST_LIST_LOCK(&domain_list); 15636 AST_LIST_INSERT_TAIL(&domain_list, d, list); 15637 AST_LIST_UNLOCK(&domain_list); 15638 15639 if (sipdebug) 15640 ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain); 15641 15642 return 1; 15643 }
| static int add_t38_sdp | ( | struct sip_request * | resp, | |
| struct sip_pvt * | p | |||
| ) | [static] |
Add T.38 Session Description Protocol message.
Definition at line 6017 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_udptl_get_local_max_datagram(), ast_udptl_get_us(), t38properties::capability, debug, t38properties::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len, LOG_DEBUG, LOG_WARNING, sip_pvt::ourip, t38properties::peercapability, s, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), t, sip_pvt::t38, t38_get_rate(), T38FAX_FILL_BIT_REMOVAL, T38FAX_RATE_MANAGEMENT_LOCAL_TCF, T38FAX_TRANSCODING_JBIG, T38FAX_TRANSCODING_MMR, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, T38FAX_VERSION, T38FAX_VERSION_0, T38FAX_VERSION_1, sip_pvt::udptl, and sip_pvt::udptlredirip.
Referenced by transmit_invite(), transmit_reinvite_with_t38_sdp(), and transmit_response_with_t38_sdp().
06018 { 06019 int len = 0; 06020 int x = 0; 06021 struct sockaddr_in udptlsin; 06022 char v[256] = ""; 06023 char s[256] = ""; 06024 char o[256] = ""; 06025 char c[256] = ""; 06026 char t[256] = ""; 06027 char m_modem[256]; 06028 char a_modem[1024]; 06029 char *m_modem_next = m_modem; 06030 size_t m_modem_left = sizeof(m_modem); 06031 char *a_modem_next = a_modem; 06032 size_t a_modem_left = sizeof(a_modem); 06033 struct sockaddr_in udptldest = { 0, }; 06034 int debug; 06035 06036 debug = sip_debug_test_pvt(p); 06037 len = 0; 06038 if (!p->udptl) { 06039 ast_log(LOG_WARNING, "No way to add SDP without an UDPTL structure\n"); 06040 return -1; 06041 } 06042 06043 if (!p->sessionid) { 06044 p->sessionid = getpid(); 06045 p->sessionversion = p->sessionid; 06046 } else 06047 p->sessionversion++; 06048 06049 /* Our T.38 end is */ 06050 ast_udptl_get_us(p->udptl, &udptlsin); 06051 06052 /* Determine T.38 UDPTL destination */ 06053 if (p->udptlredirip.sin_addr.s_addr) { 06054 udptldest.sin_port = p->udptlredirip.sin_port; 06055 udptldest.sin_addr = p->udptlredirip.sin_addr; 06056 } else { 06057 udptldest.sin_addr = p->ourip; 06058 udptldest.sin_port = udptlsin.sin_port; 06059 } 06060 06061 if (debug) 06062 ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(udptlsin.sin_port)); 06063 06064 /* We break with the "recommendation" and send our IP, in order that our 06065 peer doesn't have to ast_gethostbyname() us */ 06066 06067 if (debug) { 06068 ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n", 06069 p->t38.capability, 06070 p->t38.peercapability, 06071 p->t38.jointcapability); 06072 } 06073 snprintf(v, sizeof(v), "v=0\r\n"); 06074 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(udptldest.sin_addr)); 06075 snprintf(s, sizeof(s), "s=session\r\n"); 06076 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr)); 06077 snprintf(t, sizeof(t), "t=0 0\r\n"); 06078 ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port)); 06079 06080 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0) 06081 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n"); 06082 if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1) 06083 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n"); 06084 if ((x = t38_get_rate(p->t38.jointcapability))) 06085 ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x); 06086 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0); 06087 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0); 06088 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0); 06089 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF"); 06090 x = ast_udptl_get_local_max_datagram(p->udptl); 06091 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x); 06092 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x); 06093 if (p->t38.jointcapability != T38FAX_UDP_EC_NONE) 06094 ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC"); 06095 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_modem) + strlen(a_modem); 06096 add_header(resp, "Content-Type", "application/sdp"); 06097 add_header_contentLength(resp, len); 06098 add_line(resp, v); 06099 add_line(resp, o); 06100 add_line(resp, s); 06101 add_line(resp, c); 06102 add_line(resp, t); 06103 add_line(resp, m_modem); 06104 add_line(resp, a_modem); 06105 06106 /* Update lastrtprx when we send our SDP */ 06107 p->lastrtprx = p->lastrtptx = time(NULL); 06108 06109 return 0; 06110 }
| static int add_text | ( | struct sip_request * | req, | |
| const char * | text | |||
| ) | [static] |
Add text body to SIP message.
Definition at line 5898 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_message_with_text().
05899 { 05900 /* XXX Convert \n's to \r\n's XXX */ 05901 add_header(req, "Content-Type", "text/plain"); 05902 add_header_contentLength(req, strlen(text)); 05903 add_line(req, text); 05904 return 0; 05905 }
| static int add_vidupdate | ( | struct sip_request * | req | ) | [static] |
add XML encoded media control with update
Definition at line 5922 of file chan_sip.c.
References add_header(), add_header_contentLength(), and add_line().
Referenced by transmit_info_with_vidupdate().
05923 { 05924 const char *xml_is_a_huge_waste_of_space = 05925 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n" 05926 " <media_control>\r\n" 05927 " <vc_primitive>\r\n" 05928 " <to_encoder>\r\n" 05929 " <picture_fast_update>\r\n" 05930 " </picture_fast_update>\r\n" 05931 " </to_encoder>\r\n" 05932 " </vc_primitive>\r\n" 05933 " </media_control>\r\n"; 05934 add_header(req, "Content-Type", "application/media_control+xml"); 05935 add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space)); 05936 add_line(req, xml_is_a_huge_waste_of_space); 05937 return 0; 05938 }
| static void append_date | ( | struct sip_request * | req | ) | [static] |
Append date to SIP message.
Definition at line 5845 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().
05846 { 05847 char tmpdat[256]; 05848 struct tm tm; 05849 time_t t = time(NULL); 05850 05851 gmtime_r(&t, &tm); 05852 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm); 05853 add_header(req, "Date", tmpdat); 05854 }
| static void append_history_full | ( | struct sip_pvt * | p, | |
| const char * | fmt, | |||
| ... | ||||
| ) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1836 of file chan_sip.c.
References append_history_va().
01837 { 01838 va_list ap; 01839 01840 if (!p) 01841 return; 01842 va_start(ap, fmt); 01843 append_history_va(p, fmt, ap); 01844 va_end(ap); 01845 01846 return; 01847 }
| static void static void append_history_va | ( | struct sip_pvt * | p, | |
| const char * | fmt, | |||
| va_list | ap | |||
| ) | [static] |
Append to SIP dialog history with arg list.
Definition at line 1816 of file chan_sip.c.
References ast_calloc, AST_LIST_INSERT_TAIL, free, and strsep().
Referenced by append_history_full().
01817 { 01818 char buf[80], *c = buf; /* max history length */ 01819 struct sip_history *hist; 01820 int l; 01821 01822 vsnprintf(buf, sizeof(buf), fmt, ap); 01823 strsep(&c, "\r\n"); /* Trim up everything after \r or \n */ 01824 l = strlen(buf) + 1; 01825 if (!(hist = ast_calloc(1, sizeof(*hist) + l))) 01826 return; 01827 if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) { 01828 free(hist); 01829 return; 01830 } 01831 memcpy(hist->event, buf, l); 01832 AST_LIST_INSERT_TAIL(p->history, hist, list); 01833 }
| AST_LIST_HEAD_NOLOCK | ( | sip_history_head | , | |
| sip_history | ||||
| ) |
history list, entry in sip_pvt
| static AST_LIST_HEAD_STATIC | ( | domain_list | , | |
| domain | ||||
| ) | [static] |
The SIP domain list
| AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
| AST_MODFLAG_DEFAULT | , | |||
| "Session Initiation Protocol (SIP)" | , | |||
| . | load = load_module, |
|||
| . | unload = unload_module, |
|||
| . | reload = reload | |||
| ) |
| AST_MUTEX_DEFINE_STATIC | ( | sip_reload_lock | ) |
| AST_MUTEX_DEFINE_STATIC | ( | monlock | ) |
| AST_MUTEX_DEFINE_STATIC | ( | netlock | ) |
Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
| AST_MUTEX_DEFINE_STATIC | ( | iflock | ) |
Protect the SIP dialog list (of sip_pvt's).
| static void ast_quiet_chan | ( | struct ast_channel * | chan | ) | [static] |
Turn off generator data XXX Does this function belong in the SIP channel?
Definition at line 12746 of file chan_sip.c.
References ast_channel::_state, ast_deactivate_generator(), AST_STATE_UP, and ast_channel::generatordata.
Referenced by attempt_transfer(), and handle_invite_replaces().
12747 { 12748 if (chan && chan->_state == AST_STATE_UP) { 12749 if (chan->generatordata) 12750 ast_deactivate_generator(chan); 12751 } 12752 }
| 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 1776 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().
01777 { 01778 struct sockaddr_in theirs, ours; 01779 01780 /* Get our local information */ 01781 ast_ouraddrfor(them, us); 01782 theirs.sin_addr = *them; 01783 ours.sin_addr = *us; 01784 01785 if (localaddr && externip.sin_addr.s_addr && 01786 (ast_apply_ha(localaddr, &theirs)) && 01787 (!global_matchexterniplocally || !ast_apply_ha(localaddr, &ours))) { 01788 if (externexpire && time(NULL) >= externexpire) { 01789 struct ast_hostent ahp; 01790 struct hostent *hp; 01791 01792 externexpire = time(NULL) + externrefresh; 01793 if ((hp = ast_gethostbyname(externhost, &ahp))) { 01794 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 01795 } else 01796 ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost); 01797 } 01798 *us = externip.sin_addr; 01799 if (option_debug) { 01800 ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 01801 ast_inet_ntoa(*(struct in_addr *)&them->s_addr)); 01802 } 01803 } else if (bindaddr.sin_addr.s_addr) 01804 *us = bindaddr.sin_addr; 01805 return AST_SUCCESS; 01806 }
| AST_THREADSTORAGE_CUSTOM | ( | ts_temp_pvt | , | |
| temp_pvt_init | , | |||
| temp_pvt_cleanup | ||||
| ) |
A per-thread temporary pvt structure.
Attempt transfer of SIP call This fix for attended transfers on a local PBX.
Definition at line 12756 of file chan_sip.c.
References ast_channel::_state, ast_cdr_append(), ast_channel_masquerade(), ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_state2str(), sip_dual::chan1, sip_dual::chan2, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, and option_debug.
12757 { 12758 int res = 0; 12759 struct ast_channel *peera = NULL, 12760 *peerb = NULL, 12761 *peerc = NULL, 12762 *peerd = NULL; 12763 12764 12765 /* We will try to connect the transferee with the target and hangup 12766 all channels to the transferer */ 12767 if (option_debug > 3) { 12768 ast_log(LOG_DEBUG, "Sip transfer:--------------------\n"); 12769 if (transferer->chan1) 12770 ast_log(LOG_DEBUG, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state)); 12771 else 12772 ast_log(LOG_DEBUG, "-- No transferer first channel - odd??? \n"); 12773 if (target->chan1) 12774 ast_log(LOG_DEBUG, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state)); 12775 else 12776 ast_log(LOG_DEBUG, "-- No target first channel ---\n"); 12777 if (transferer->chan2) 12778 ast_log(LOG_DEBUG, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state)); 12779 else 12780 ast_log(LOG_DEBUG, "-- No bridged call to transferee\n"); 12781 if (target->chan2) 12782 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)"); 12783 else 12784 ast_log(LOG_DEBUG, "-- No target second channel ---\n"); 12785 ast_log(LOG_DEBUG, "-- END Sip transfer:--------------------\n"); 12786 } 12787 if (transferer->chan2) { /* We have a bridge on the transferer's channel */ 12788 peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */ 12789 peerb = target->chan1; /* Transferer - PBX -> target channel - This will get lost in masq */ 12790 peerc = transferer->chan2; /* Asterisk to Transferee */ 12791 peerd = target->chan2; /* Asterisk to Target */ 12792 if (option_debug > 2) 12793 ast_log(LOG_DEBUG, "SIP transfer: Four channels to handle\n"); 12794 } else if (target->chan2) { /* Transferer has no bridge (IVR), but transferee */ 12795 peera = target->chan1; /* Transferer to PBX -> target channel */ 12796 peerb = transferer->chan1; /* Transferer to IVR*/ 12797 peerc = target->chan2; /* Asterisk to Target */ 12798 peerd = transferer->chan2; /* Nothing */ 12799 if (option_debug > 2) 12800 ast_log(LOG_DEBUG, "SIP transfer: Three channels to handle\n"); 12801 } 12802 12803 if (peera && peerb && peerc && (peerb != peerc)) { 12804 ast_quiet_chan(peera); /* Stop generators */ 12805 ast_quiet_chan(peerb); 12806 ast_quiet_chan(peerc); 12807 if (peerd) 12808 ast_quiet_chan(peerd); 12809 12810 /* Fix CDRs so they're attached to the remaining channel */ 12811 if (peera->cdr && peerb->cdr) 12812 peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr); 12813 else if (peera->cdr) 12814 peerb->cdr = peera->cdr; 12815 peera->cdr = NULL; 12816 12817 if (peerb->cdr && peerc->cdr) 12818 peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr); 12819 else if (peerc->cdr) 12820 peerb->cdr = peerc->cdr; 12821 peerc->cdr = NULL; 12822 12823 if (option_debug > 3) 12824 ast_log(LOG_DEBUG, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name); 12825 if (ast_channel_masquerade(peerb, peerc)) { 12826 ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name); 12827 res = -1; 12828 } else 12829 ast_log(LOG_DEBUG, "SIP transfer: Succeeded to masquerade channels.\n"); 12830 return res; 12831 } else { 12832 ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n"); 12833 if (transferer->chan1) 12834 ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV); 12835 if (target->chan1) 12836 ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV); 12837 return -1; 12838 } 12839 return 0; 12840 }
| static int auto_congest | ( | void * | nothing | ) | [static] |
Scheduled congestion on a call.
Definition at line 2749 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_CONGESTION, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_control(), sip_pvt::initid, sip_pvt::lock, LOG_NOTICE, and sip_pvt::owner.
02750 { 02751 struct sip_pvt *p = nothing; 02752 02753 ast_mutex_lock(&p->lock); 02754 p->initid = -1; 02755 if (p->owner) { 02756 /* XXX fails on possible deadlock */ 02757 if (!ast_channel_trylock(p->owner)) { 02758 ast_log(LOG_NOTICE, "Auto-congesting %s\n", p->owner->name); 02759 append_history(p, "Cong", "Auto-congesting (timer)"); 02760 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 02761 ast_channel_unlock(p->owner); 02762 } 02763 } 02764 ast_mutex_unlock(&p->lock); 02765 return 0; 02766 }
| static void build_callid_pvt | ( | struct sip_pvt * | pvt | ) | [static] |
Build SIP Call-ID value for a non-REGISTER transaction.
Definition at line 4175 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, generate_random_string(), sip_pvt::ourip, and S_OR.
Referenced by sip_alloc(), sip_notify(), sip_poke_peer(), sip_request_call(), and sip_send_mwi_to_peer().
04176 { 04177 char buf[33]; 04178 04179 const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip)); 04180 04181 ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04182 04183 }
| 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 4186 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, generate_random_string(), and S_OR.
Referenced by transmit_register().
04187 { 04188 char buf[33]; 04189 04190 const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip)); 04191 04192 ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host); 04193 }
| static void build_contact | ( | struct sip_pvt * | p | ) | [static] |
Build contact header - the contact header we send out.
Definition at line 6558 of file chan_sip.c.
References ast_inet_ntoa(), ast_string_field_build, ast_strlen_zero(), ourport, and STANDARD_SIP_PORT.
Referenced by check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), initreqprep(), register_verify(), and transmit_register().
06559 { 06560 /* Construct Contact: header */ 06561 if (ourport != STANDARD_SIP_PORT) 06562 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); 06563 else 06564 ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip)); 06565 }
| 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 15946 of file chan_sip.c.
References sip_peer::accountcode, add_realm_authentication(), sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), ast_get_group(), ast_get_ip(), ast_get_ip_or_srv(), ast_get_time_t(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_sched_del(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), ast_variables_destroy(), ASTOBJ_CONTAINER_FIND_UNLINK_FULL, ASTOBJ_FLAG_MARKED, ASTOBJ_INIT, ASTOBJ_UNMARK, ASTOBJ_UNREF, sip_peer::auth, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::defaddr, DEFAULT_MAXMS, destroy_association(), sip_peer::expire, ast_flags::flags, sip_peer::flags, format, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_flags, sip_peer::ha, handle_common_options(), sip_peer::language, sip_peer::lastmsgssent, ast_variable::lineno, LOG_DEBUG, LOG_WARNING, sip_peer::mailbox, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, ast_variable::name, ast_variable::next, option_debug, peerl, sip_peer::pickupgroup, sip_peer::prefs, reg_source_db(), sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sched, sip_peer::secret, set_peer_defaults(), sip_destroy_peer(), SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_REALTIME, SIP_USEREQPHONE, STANDARD_SIP_PORT, sip_peer::subscribecontext, sip_peer::tohost, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, sip_peer::username, ast_variable::value, and sip_peer::vmexten.
15947 { 15948 struct sip_peer *peer = NULL; 15949 struct ast_ha *oldha = NULL; 15950 int obproxyfound=0; 15951 int found=0; 15952 int firstpass=1; 15953 int format=0; /* Ama flags */ 15954 time_t regseconds = 0; 15955 char *varname = NULL, *varval = NULL; 15956 struct ast_variable *tmpvar = NULL; 15957 struct ast_flags peerflags[2] = {{(0)}}; 15958 struct ast_flags mask[2] = {{(0)}}; 15959 15960 15961 if (!realtime) 15962 /* Note we do NOT use find_peer here, to avoid realtime recursion */ 15963 /* We also use a case-sensitive comparison (unlike find_peer) so 15964 that case changes made to the peer name will be properly handled 15965 during reload 15966 */ 15967 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 15968 15969 if (peer) { 15970 /* Already in the list, remove it and it will be added back (or FREE'd) */ 15971 found = 1; 15972 if (!(peer->objflags & ASTOBJ_FLAG_MARKED)) 15973 firstpass = 0; 15974 } else { 15975 if (!(peer = ast_calloc(1, sizeof(*peer)))) 15976 return NULL; 15977 15978 if (realtime) 15979 rpeerobjs++; 15980 else 15981 speerobjs++; 15982 ASTOBJ_INIT(peer); 15983 } 15984 /* Note that our peer HAS had its reference count incrased */ 15985 if (firstpass) { 15986 peer->lastmsgssent = -1; 15987 oldha = peer->ha; 15988 peer->ha = NULL; 15989 set_peer_defaults(peer); /* Set peer defaults */ 15990 } 15991 if (!found && name) 15992 ast_copy_string(peer->name, name, sizeof(peer->name)); 15993 15994 /* If we have channel variables, remove them (reload) */ 15995 if (peer->chanvars) { 15996 ast_variables_destroy(peer->chanvars); 15997 peer->chanvars = NULL; 15998 /* XXX should unregister ? */ 15999 } 16000 for (; v || ((v = alt) && !(alt=NULL)); v = v->next) { 16001 if (handle_common_options(&peerflags[0], &mask[0], v)) 16002 continue; 16003 if (realtime && !strcasecmp(v->name, "regseconds")) { 16004 ast_get_time_t(v->value, ®seconds, 0, NULL); 16005 } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) { 16006 inet_aton(v->value, &(peer->addr.sin_addr)); 16007 } else if (realtime && !strcasecmp(v->name, "name")) 16008 ast_copy_string(peer->name, v->value, sizeof(peer->name)); 16009 else if (realtime && !strcasecmp(v->name, "fullcontact")) { 16010 ast_copy_string(peer->fullcontact, v->value, sizeof(peer->fullcontact)); 16011 ast_set_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT); 16012 } else if (!strcasecmp(v->name, "secret")) 16013 ast_copy_string(peer->secret, v->value, sizeof(peer->secret)); 16014 else if (!strcasecmp(v->name, "md5secret")) 16015 ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret)); 16016 else if (!strcasecmp(v->name, "auth")) 16017 peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); 16018 else if (!strcasecmp(v->name, "callerid")) { 16019 ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num)); 16020 } else if (!strcasecmp(v->name, "fullname")) { 16021 ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name)); 16022 } else if (!strcasecmp(v->name, "cid_number")) { 16023 ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num)); 16024 } else if (!strcasecmp(v->name, "context")) { 16025 ast_copy_string(peer->context, v->value, sizeof(peer->context)); 16026 } else if (!strcasecmp(v->name, "subscribecontext")) { 16027 ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext)); 16028 } else if (!strcasecmp(v->name, "fromdomain")) { 16029 ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain)); 16030 } else if (!strcasecmp(v->name, "usereqphone")) { 16031 ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE); 16032 } else if (!strcasecmp(v->name, "fromuser")) { 16033 ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser)); 16034 } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { 16035 if (!strcasecmp(v->value, "dynamic")) { 16036 if (!strcasecmp(v->name, "outboundproxy") || obproxyfound) { 16037 ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno); 16038 } else { 16039 /* They'll register with us */ 16040 if (!found || !ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 16041 /* Initialize stuff if this is a new peer, or if it used to be 16042 * non-dynamic before the reload. */ 16043 memset(&peer->addr.sin_addr, 0, 4); 16044 if (peer->addr.sin_port) { 16045 /* If we've already got a port, make it the default rather than absolute */ 16046 peer->defaddr.sin_port = peer->addr.sin_port; 16047 peer->addr.sin_port = 0; 16048 } 16049 } 16050 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16051 } 16052 } else { 16053 /* Non-dynamic. Make sure we become that way if we're not */ 16054 if (peer->expire > -1) 16055 ast_sched_del(sched, peer->expire); 16056 peer->expire = -1; 16057 ast_clear_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 16058 if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) { 16059 if (ast_get_ip_or_srv(&peer->addr, v->value, srvlookup ? "_sip._udp" : NULL)) { 16060 ASTOBJ_UNREF(peer, sip_destroy_peer); 16061 return NULL; 16062 } 16063 } 16064 if (!strcasecmp(v->name, "outboundproxy")) 16065 obproxyfound=1; 16066 else { 16067 ast_copy_string(peer->tohost, v->value, sizeof(peer->tohost)); 16068 if (!peer->addr.sin_port) 16069 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 16070 } 16071 } 16072 } else if (!strcasecmp(v->name, "defaultip")) { 16073 if (ast_get_ip(&peer->defaddr, v->value)) { 16074 ASTOBJ_UNREF(peer, sip_destroy_peer); 16075 return NULL; 16076 } 16077 } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { 16078 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 16079 } else if (!strcasecmp(v->name, "port")) { 16080 if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) 16081 peer->defaddr.sin_port = htons(atoi(v->value)); 16082 else 16083 peer->addr.sin_port = htons(atoi(v->value)); 16084 } else if (!strcasecmp(v->name, "callingpres")) { 16085 peer->callingpres = ast_parse_caller_presentation(v->value); 16086 if (peer->callingpres == -1) 16087 peer->callingpres = atoi(v->value); 16088 } else if (!strcasecmp(v->name, "username")) { 16089 ast_copy_string(peer->username, v->value, sizeof(peer->username)); 16090 } else if (!strcasecmp(v->name, "language")) { 16091 ast_copy_string(peer->language, v->value, sizeof(peer->language)); 16092 } else if (!strcasecmp(v->name, "regexten")) { 16093 ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten)); 16094 } else if (!strcasecmp(v->name, "call-limit") || !strcasecmp(v->name, "incominglimit")) { 16095 peer->call_limit = atoi(v->value); 16096 if (peer->call_limit < 0) 16097 peer->call_limit = 0; 16098 } else if (!strcasecmp(v->name, "amaflags")) { 16099 format = ast_cdr_amaflags2int(v->value); 16100 if (format < 0) { 16101 ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno); 16102 } else { 16103 peer->amaflags = format; 16104 } 16105 } else if (!strcasecmp(v->name, "accountcode")) { 16106 ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); 16107 } else if (!strcasecmp(v->name, "mohinterpret") 16108 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16109 ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret)); 16110 } else if (!strcasecmp(v->name, "mohsuggest")) { 16111 ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest)); 16112 } else if (!strcasecmp(v->name, "mailbox")) { 16113 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 16114 } else if (!strcasecmp(v->name, "subscribemwi")) { 16115 ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY); 16116 } else if (!strcasecmp(v->name, "vmexten")) { 16117 ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten)); 16118 } else if (!strcasecmp(v->name, "callgroup")) { 16119 peer->callgroup = ast_get_group(v->value); 16120 } else if (!strcasecmp(v->name, "allowtransfer")) { 16121 peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16122 } else if (!strcasecmp(v->name, "pickupgroup")) { 16123 peer->pickupgroup = ast_get_group(v->value); 16124 } else if (!strcasecmp(v->name, "allow")) { 16125 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 16126 } else if (!strcasecmp(v->name, "disallow")) { 16127 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 16128 } else if (!strcasecmp(v->name, "autoframing")) { 16129 peer->autoframing = ast_true(v->value); 16130 } else if (!strcasecmp(v->name, "rtptimeout")) { 16131 if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) { 16132 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16133 peer->rtptimeout = global_rtptimeout; 16134 } 16135 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 16136 if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) { 16137 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16138 peer->rtpholdtimeout = global_rtpholdtimeout; 16139 } 16140 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 16141 if ((sscanf(v->value, "%d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) { 16142 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 16143 peer->rtpkeepalive = global_rtpkeepalive; 16144 } 16145 } else if (!strcasecmp(v->name, "setvar")) { 16146 /* Set peer channel variable */ 16147 varname = ast_strdupa(v->value); 16148 if ((varval = strchr(varname, '='))) { 16149 *varval++ = '\0'; 16150 if ((tmpvar = ast_variable_new(varname, varval))) { 16151 tmpvar->next = peer->chanvars; 16152 peer->chanvars = tmpvar; 16153 } 16154 } 16155 } else if (!strcasecmp(v->name, "qualify")) { 16156 if (!strcasecmp(v->value, "no")) { 16157 peer->maxms = 0; 16158 } else if (!strcasecmp(v->value, "yes")) { 16159 peer->maxms = DEFAULT_MAXMS; 16160 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 16161 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); 16162 peer->maxms = 0; 16163 } 16164 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16165 peer->maxcallbitrate = atoi(v->value); 16166 if (peer->maxcallbitrate < 0) 16167 peer->maxcallbitrate = default_maxcallbitrate; 16168 } 16169 } 16170 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && realtime) { 16171 time_t nowtime = time(NULL); 16172 16173 if ((nowtime - regseconds) > 0) { 16174 destroy_association(peer); 16175 memset(&peer->addr, 0, sizeof(peer->addr)); 16176 if (option_debug) 16177 ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 16178 } 16179 } 16180 ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags); 16181 ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags); 16182 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 16183 global_allowsubscribe = TRUE; /* No global ban any more */ 16184 if (!found && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&peer->flags[0], SIP_REALTIME)) 16185 reg_source_db(peer); 16186 ASTOBJ_UNMARK(peer); 16187 ast_free_ha(oldha); 16188 return peer; 16189 }
| static int build_reply_digest | ( | struct sip_pvt * | p, | |
| int | method, | |||
| char * | digest, | |||
| int | digest_len | |||
| ) | [static] |
Build reply digest.
Definition at line 11187 of file chan_sip.c.
References append_history, ast_inet_ntoa(), ast_log(), ast_md5_hash(), ast_random(), ast_strlen_zero(), authl, find_realm_authentication(), LOG_DEBUG, LOG_WARNING, sip_auth::md5secret, sip_pvt::noncecount, sip_pvt::sa, sip_auth::secret, secret, sip_methods, sipdebug, text, sip_auth::username, and username.
Referenced by reply_digest(), transmit_register(), and transmit_request_with_auth().
11188 { 11189 char a1[256]; 11190 char a2[256]; 11191 char a1_hash[256]; 11192 char a2_hash[256]; 11193 char resp[256]; 11194 char resp_hash[256]; 11195 char uri[256]; 11196 char cnonce[80]; 11197 const char *username; 11198 const char *secret; 11199 const char *md5secret; 11200 struct sip_auth *auth = NULL; /* Realm authentication */ 11201 11202 if (!ast_strlen_zero(p->domain)) 11203 ast_copy_string(uri, p->domain, sizeof(uri)); 11204 else if (!ast_strlen_zero(p->uri)) 11205 ast_copy_string(uri, p->uri, sizeof(uri)); 11206 else 11207 snprintf(uri, sizeof(uri), "sip:%s@%s",p->username, ast_inet_ntoa(p->sa.sin_addr)); 11208 11209 snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); 11210 11211 /* Check if we have separate auth credentials */ 11212 if ((auth = find_realm_authentication(authl, p->realm))) { 11213 ast_log(LOG_WARNING, "use realm [%s] from peer [%s][%s]\n", 11214 auth->username, p->peername, p->username); 11215 username = auth->username; 11216 secret = auth->secret; 11217 md5secret = auth->md5secret; 11218 if (sipdebug) 11219 ast_log(LOG_DEBUG,"Using realm %s authentication for call %s\n", p->realm, p->callid); 11220 } else { 11221 /* No authentication, use peer or register= config */ 11222 username = p->authname; 11223 secret = p->peersecret; 11224 md5secret = p->peermd5secret; 11225 } 11226 if (ast_strlen_zero(username)) /* We have no authentication */ 11227 return -1; 11228 11229 /* Calculate SIP digest response */ 11230 snprintf(a1,sizeof(a1),"%s:%s:%s", username, p->realm, secret); 11231 snprintf(a2,sizeof(a2),"%s:%s", sip_methods[method].text, uri); 11232 if (!ast_strlen_zero(md5secret)) 11233 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 11234 else 11235 ast_md5_hash(a1_hash,a1); 11236 ast_md5_hash(a2_hash,a2); 11237 11238 p->noncecount++; 11239 if (!ast_strlen_zero(p->qop)) 11240 snprintf(resp,sizeof(resp),"%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash); 11241 else 11242 snprintf(resp,sizeof(resp),"%s:%s:%s", a1_hash, p->nonce, a2_hash); 11243 ast_md5_hash(resp_hash, resp); 11244 /* XXX We hard code our qop to "auth" for now. XXX */ 11245 if (!ast_strlen_zero(p->qop)) 11246 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\", opaque=\"%s\", qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, p->opaque, cnonce, p->noncecount); 11247 else 11248 snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\", opaque=\"%s\"", username, p->realm, uri, p->nonce, resp_hash, p->opaque); 11249 11250 append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); 11251 11252 return 0; 11253 }
| 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 7933 of file chan_sip.c.
References __get_header(), ast_log(), ast_malloc, ast_strlen_zero(), free_old_route(), get_header(), sip_route::hop, len, list_route(), LOG_DEBUG, sip_route::next, option_debug, sip_pvt::route, sip_pvt::route_persistant, and sip_debug_test_pvt().
Referenced by handle_request_invite(), and handle_response_invite().
07934 { 07935 struct sip_route *thishop, *head, *tail; 07936 int start = 0; 07937 int len; 07938 const char *rr, *contact, *c; 07939 07940 /* Once a persistant route is set, don't fool with it */ 07941 if (p->route && p->route_persistant) { 07942 if (option_debug) 07943 ast_log(LOG_DEBUG, "build_route: Retaining previous route: <%s>\n", p->route->hop); 07944 return; 07945 } 07946 07947 if (p->route) { 07948 free_old_route(p->route); 07949 p->route = NULL; 07950 } 07951 07952 p->route_persistant = backwards; 07953 07954 /* Build a tailq, then assign it to p->route when done. 07955 * If backwards, we add entries from the head so they end up 07956 * in reverse order. However, we do need to maintain a correct 07957 * tail pointer because the contact is always at the end. 07958 */ 07959 head = NULL; 07960 tail = head; 07961 /* 1st we pass through all the hops in any Record-Route headers */ 07962 for (;;) { 07963 /* Each Record-Route header */ 07964 rr = __get_header(req, "Record-Route", &start); 07965 if (*rr == '\0') 07966 break; 07967 for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */ 07968 ++rr; 07969 len = strcspn(rr, ">") + 1; 07970 /* Make a struct route */ 07971 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 07972 /* ast_calloc is not needed because all fields are initialized in this block */ 07973 ast_copy_string(thishop->hop, rr, len); 07974 if (option_debug > 1) 07975 ast_log(LOG_DEBUG, "build_route: Record-Route hop: <%s>\n", thishop->hop); 07976 /* Link in */ 07977 if (backwards) { 07978 /* Link in at head so they end up in reverse order */ 07979 thishop->next = head; 07980 head = thishop; 07981 /* If this was the first then it'll be the tail */ 07982 if (!tail) 07983 tail = thishop; 07984 } else { 07985 thishop->next = NULL; 07986 /* Link in at the end */ 07987 if (tail) 07988 tail->next = thishop; 07989 else 07990 head = thishop; 07991 tail = thishop; 07992 } 07993 } 07994 } 07995 } 07996 07997 /* Only append the contact if we are dealing with a strict router */ 07998 if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) { 07999 /* 2nd append the Contact: if there is one */ 08000 /* Can be multiple Contact headers, comma separated values - we just take the first */ 08001 contact = get_header(req, "Contact"); 08002 if (!ast_strlen_zero(contact)) { 08003 if (option_debug > 1) 08004 ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact); 08005 /* Look for <: delimited address */ 08006 c = strchr(contact, '<'); 08007 if (c) { 08008 /* Take to > */ 08009 ++c; 08010 len = strcspn(c, ">") + 1; 08011 } else { 08012 /* No <> - just take the lot */ 08013 c = contact; 08014 len = strlen(contact) + 1; 08015 } 08016 if ((thishop = ast_malloc(sizeof(*thishop) + len))) { 08017 /* ast_calloc is not needed because all fields are initialized in this block */ 08018 ast_copy_string(thishop->hop, c, len); 08019 thishop->next = NULL; 08020 /* Goes at the end */ 08021 if (tail) 08022 tail->next = thishop; 08023 else 08024 head = thishop; 08025 } 08026 } 08027 } 08028 08029 /* Store as new route */ 08030 p->route = head; 08031 08032 /* For debugging dump what we ended up with */ 08033 if (sip_debug_test_pvt(p)) 08034 list_route(p->route); 08035 }
| static void build_rpid | ( | struct sip_pvt * | p | ) | [static] |
Build the Remote Party-ID & From using callingpres options.
Definition at line 6568 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED, AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, AST_PRES_RESTRICTION, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, FALSE, LOG_WARNING, sip_pvt::ourip, sip_pvt::owner, S_OR, sip_pvt::tag, and TRUE.
Referenced by initreqprep().
06569 { 06570 int send_pres_tags = TRUE; 06571 const char *privacy=NULL; 06572 const char *screen=NULL; 06573 char buf[256]; 06574 const char *clid = default_callerid; 06575 const char *clin = NULL; 06576 const char *fromdomain; 06577 06578 if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from)) 06579 return; 06580 06581 if (p->owner && p->owner->cid.cid_num) 06582 clid = p->owner->cid.cid_num; 06583 if (p->owner && p->owner->cid.cid_name) 06584 clin = p->owner->cid.cid_name; 06585 if (ast_strlen_zero(clin)) 06586 clin = clid; 06587 06588 switch (p->callingpres) { 06589 case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: 06590 privacy = "off"; 06591 screen = "no"; 06592 break; 06593 case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: 06594 privacy = "off"; 06595 screen = "yes"; 06596 break; 06597 case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: 06598 privacy = "off"; 06599 screen = "no"; 06600 break; 06601 case AST_PRES_ALLOWED_NETWORK_NUMBER: 06602 privacy = "off"; 06603 screen = "yes"; 06604 break; 06605 case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: 06606 privacy = "full"; 06607 screen = "no"; 06608 break; 06609 case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: 06610 privacy = "full"; 06611 screen = "yes"; 06612 break; 06613 case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: 06614 privacy = "full"; 06615 screen = "no"; 06616 break; 06617 case AST_PRES_PROHIB_NETWORK_NUMBER: 06618 privacy = "full"; 06619 screen = "yes"; 06620 break; 06621 case AST_PRES_NUMBER_NOT_AVAILABLE: 06622 send_pres_tags = FALSE; 06623 break; 06624 default: 06625 ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres); 06626 if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) 06627 privacy = "full"; 06628 else 06629 privacy = "off"; 06630 screen = "no"; 06631 break; 06632 } 06633 06634 fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)); 06635 06636 snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain); 06637 if (send_pres_tags) 06638 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen); 06639 ast_string_field_set(p, rpid, buf); 06640 06641 ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin, 06642 S_OR(p->fromuser, clid), 06643 fromdomain, p->tag); 06644 }
| static struct sip_user * build_user | ( | const char * | name, | |
| struct ast_variable * | v, | |||
| int | realtime | |||
| ) | [static] |
Initiate a SIP user structure from configuration (configuration or realtime).
Definition at line 15767 of file chan_sip.c.
References sip_user::allowtransfer, ast_append_ha(), ast_calloc, ast_copy_flags, ast_strdupa, ast_true(), ast_variable_new(), ASTOBJ_INIT, sip_user::chanvars, default_prefs, format, global_flags, sip_user::ha, handle_common_options(), ast_variable::name, ast_variable::next, sip_user::secret, SIP_FLAGS_TO_COPY, SIP_PAGE2_FLAGS_TO_COPY, TRANSFER_CLOSED, TRANSFER_OPENFORALL, and ast_variable::value.
15768 { 15769 struct sip_user *user; 15770 int format; 15771 struct ast_ha *oldha = NULL; 15772 char *varname = NULL, *varval = NULL; 15773 struct ast_variable *tmpvar = NULL; 15774 struct ast_flags userflags[2] = {{(0)}}; 15775 struct ast_flags mask[2] = {{(0)}}; 15776 15777 15778 if (!(user = ast_calloc(1, sizeof(*user)))) 15779 return NULL; 15780 15781 suserobjs++; 15782 ASTOBJ_INIT(user); 15783 ast_copy_string(user->name, name, sizeof(user->name)); 15784 oldha = user->ha; 15785 user->ha = NULL; 15786 ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 15787 ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 15788 user->capability = global_capability; 15789 user->allowtransfer = global_allowtransfer; 15790 user->maxcallbitrate = default_maxcallbitrate; 15791 user->autoframing = global_autoframing; 15792 user->prefs = default_prefs; 15793 /* set default context */ 15794 strcpy(user->context, default_context); 15795 strcpy(user->language, default_language); 15796 strcpy(user->mohinterpret, default_mohinterpret); 15797 strcpy(user->mohsuggest, default_mohsuggest); 15798 for (; v; v = v->next) { 15799 if (handle_common_options(&userflags[0], &mask[0], v)) 15800 continue; 15801 15802 if (!strcasecmp(v->name, "context")) { 15803 ast_copy_string(user->context, v->value, sizeof(user->context)); 15804 } else if (!strcasecmp(v->name, "subscribecontext")) { 15805 ast_copy_string(user->subscribecontext, v->value, sizeof(user->subscribecontext)); 15806 } else if (!strcasecmp(v->name, "setvar")) { 15807 varname = ast_strdupa(v->value); 15808 if ((varval = strchr(varname,'='))) { 15809 *varval++ = '\0'; 15810 if ((tmpvar = ast_variable_new(varname, varval))) { 15811 tmpvar->next = user->chanvars; 15812 user->chanvars = tmpvar; 15813 } 15814 } 15815 } else if (!strcasecmp(v->name, "permit") || 15816 !strcasecmp(v->name, "deny")) { 15817 user->ha = ast_append_ha(v->name, v->value, user->ha); 15818 } else if (!strcasecmp(v->name, "allowtransfer")) { 15819 user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 15820 } else if (!strcasecmp(v->name, "secret")) { 15821 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 15822 } else if (!strcasecmp(v->name, "md5secret")) { 15823 ast_copy_string(user->md5secret, v->value, sizeof(user->md5secret)); 15824 } else if (!strcasecmp(v->name, "callerid")) { 15825 ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num)); 15826 } else if (!strcasecmp(v->name, "fullname")) { 15827 ast_copy_string(user->cid_name, v->value, sizeof(user->cid_name)); 15828 } else if (!strcasecmp(v->name, "cid_number")) { 15829 ast_copy_string(user->cid_num, v->value, sizeof(user->cid_num)); 15830 } else if (!strcasecmp(v->name, "callgroup")) { 15831 user->callgroup = ast_get_group(v->value); 15832 } else if (!strcasecmp(v->name, "pickupgroup")) { 15833 user->pickupgroup = ast_get_group(v->value); 15834 } else if (!strcasecmp(v->name, "language")) { 15835 ast_copy_string(user->language, v->value, sizeof(user->language)); 15836 } else if (!strcasecmp(v->name, "mohinterpret") 15837 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 15838 ast_copy_string(user->mohinterpret, v->value, sizeof(user->mohinterpret)); 15839 } else if (!strcasecmp(v->name, "mohsuggest")) { 15840 ast_copy_string(user->mohsuggest, v->value, sizeof(user->mohsuggest)); 15841 } else if (!strcasecmp(v->name, "accountcode")) { 15842 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 15843 } else if (!strcasecmp(v->name, "call-limit")) { 15844 user->call_limit = atoi(v->value); 15845 if (user->call_limit < 0) 15846 user->call_limit = 0; 15847 } else if (!strcasecmp(v->name, "amaflags")) { 15848 format = ast_cdr_amaflags2int(v->value); 15849 if (format < 0) { 15850 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 15851 } else { 15852 user->amaflags = format; 15853 } 15854 } else if (!strcasecmp(v->name, "allow")) { 15855 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 15856 } else if (!strcasecmp(v->name, "disallow")) { 15857 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); 15858 } else if (!strcasecmp(v->name, "autoframing")) { 15859 user->autoframing = ast_true(v->value); 15860 } else if (!strcasecmp(v->name, "callingpres")) { 15861 user->callingpres = ast_parse_caller_presentation(v->value); 15862 if (user->callingpres == -1) 15863 user->callingpres = atoi(v->value); 15864 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 15865 user->maxcallbitrate = atoi(v->value); 15866 if (user->maxcallbitrate < 0) 15867 user->maxcallbitrate = default_maxcallbitrate; 15868 } 15869 /* We can't just report unknown options here because this may be a 15870 * type=friend entry. All user options are valid for a peer, but not 15871 * the other way around. */ 15872 } 15873 ast_copy_flags(&user->flags[0], &userflags[0], mask[0].flags); 15874 ast_copy_flags(&user->flags[1], &userflags[1], mask[1].flags); 15875 if (ast_test_flag(&user->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) 15876 global_allowsubscribe = TRUE; /* No global ban any more */ 15877 ast_free_ha(oldha); 15878 return user; 15879 }
| static void build_via | ( | struct sip_pvt * | p | ) | [static] |
Build a Via header for a request.
Definition at line 1760 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().
01761 { 01762 /* Work around buggy UNIDEN UIP200 firmware */ 01763 const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : ""; 01764 01765 /* z9hG4bK is a magic cookie. See RFC 3261 section 8.1.1.7 */ 01766 ast_string_field_build(p, via, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s", 01767 ast_inet_ntoa(p->ourip), ourport, p->branch, rport); 01768 }
| static int cb_extensionstate | ( | char * | context, | |
| char * | exten, | |||
| int | state, | |||
| void * | data | |||
| ) | [static] |
Callback for the devicestate notification (SUBSCRIBE) support subsystem.
Definition at line 8225 of file chan_sip.c.
References append_history, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_verbose(), sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::laststate, NONE, option_verbose, sip_cancel_destroy(), sip_scheddestroy(), sip_pvt::stateid, sip_pvt::subscribed, transmit_state_notify(), VERBOSE_PREFIX_1, and VERBOSE_PREFIX_2.
Referenced by handle_request_subscribe().
08226 { 08227 struct sip_pvt *p = data; 08228 08229 switch(state) { 08230 case AST_EXTENSION_DEACTIVATED: /* Retry after a while */ 08231 case AST_EXTENSION_REMOVED: /* Extension is gone */ 08232 if (p->autokillid > -1) 08233 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 08234 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); /* Delete subscription in 32 secs */ 08235 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); 08236 p->stateid = -1; 08237 p->subscribed = NONE; 08238 append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated"); 08239 break; 08240 default: /* Tell user */ 08241 p->laststate = state; 08242 break; 08243 } 08244 if (p->subscribed != NONE) /* Only send state NOTIFY if we know the format */ 08245 transmit_state_notify(p, state, 1, FALSE); 08246 08247 if (option_verbose > 1) 08248 ast_verbose(VERBOSE_PREFIX_1 "Extension Changed %s new state %s for Notify User %s\n", exten, ast_extension_state2str(state), p->username); 08249 return 0; 08250 }
| static enum check_auth_result check_auth | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| const char * | username, | |||
| const char * | secret, | |||
| const char * | md5secret, | |||
| int | sipmethod, | |||
| char * | uri, | |||
| enum xmittype | reliable, | |||
| int | ignore | |||
| ) | [static] |
Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).
Definition at line 8043 of file chan_sip.c.
References append_history, ast_log(), ast_md5_hash(), ast_random(), ast_string_field_build, ast_strlen_zero(), AUTH_CHALLENGE_SENT, AUTH_SUCCESSFUL, AUTH_USERNAME_MISMATCH, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), key(), keys, LOG_NOTICE, LOG_WARNING, s, S_OR, sip_methods, SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, sipdebug, strsep(), text, transmit_response_with_auth(), and TRUE.
Referenced by check_user_full(), and register_verify().
08046 { 08047 const char *response = "407 Proxy Authentication Required"; 08048 const char *reqheader = "Proxy-Authorization"; 08049 const char *respheader = "Proxy-Authenticate"; 08050 const char *authtoken; 08051 char a1_hash[256]; 08052 char resp_hash[256]=""; 08053 char tmp[BUFSIZ * 2]; /* Make a large enough buffer */ 08054 char *c; 08055 int wrongnonce = FALSE; 08056 int good_response; 08057 const char *usednonce = p->randdata; 08058 08059 /* table of recognised keywords, and their value in the digest */ 08060 enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST }; 08061 struct x { 08062 const char *key; 08063 const char *s; 08064 } *i, keys[] = { 08065 [K_RESP] = { "response=", "" }, 08066 [K_URI] = { "uri=", "" }, 08067 [K_USER] = { "username=", "" }, 08068 [K_NONCE] = { "nonce=", "" }, 08069 [K_LAST] = { NULL, NULL} 08070 }; 08071 08072 /* Always OK if no secret */ 08073 if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret)) 08074 return AUTH_SUCCESSFUL; 08075 if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) { 08076 /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family 08077 of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in 08078 different circumstances! What a surprise. */ 08079 response = "401 Unauthorized"; 08080 reqheader = "Authorization"; 08081 respheader = "WWW-Authenticate"; 08082 } 08083 authtoken = get_header(req, reqheader); 08084 if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) { 08085 /* This is a retransmitted invite/register/etc, don't reconstruct authentication 08086 information */ 08087 if (!reliable) { 08088 /* Resend message if this was NOT a reliable delivery. Otherwise the 08089 retransmission should get it */ 08090 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08091 /* Schedule auto destroy in 32 seconds (according to RFC 3261) */ 08092 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08093 } 08094 return AUTH_CHALLENGE_SENT; 08095 } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) { 08096 /* We have no auth, so issue challenge and request authentication */ 08097 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08098 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08099 /* Schedule auto destroy in 32 seconds */ 08100 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08101 return AUTH_CHALLENGE_SENT; 08102 } 08103 08104 /* --- We have auth, so check it */ 08105 08106 /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting 08107 an example in the spec of just what it is you're doing a hash on. */ 08108 08109 08110 /* Make a copy of the response and parse it */ 08111 ast_copy_string(tmp, authtoken, sizeof(tmp)); 08112 c = tmp; 08113 08114 while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */ 08115 for (i = keys; i->key != NULL; i++) { 08116 const char *separator = ","; /* default */ 08117 08118 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 08119 continue; 08120 /* Found. Skip keyword, take text in quotes or up to the separator. */ 08121 c += strlen(i->key); 08122 if (*c == '"') { /* in quotes. Skip first and look for last */ 08123 c++; 08124 separator = "\""; 08125 } 08126 i->s = c; 08127 strsep(&c, separator); 08128 break; 08129 } 08130 if (i->key == NULL) /* not found, jump after space or comma */ 08131 strsep(&c, " ,"); 08132 } 08133 08134 /* Verify that digest username matches the username we auth as */ 08135 if (strcmp(username, keys[K_USER].s)) { 08136 ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", 08137 username, keys[K_USER].s); 08138 /* Oops, we're trying something here */ 08139 return AUTH_USERNAME_MISMATCH; 08140 } 08141 08142 /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */ 08143 if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */ 08144 wrongnonce = TRUE; 08145 usednonce = keys[K_NONCE].s; 08146 } 08147 08148 if (!ast_strlen_zero(md5secret)) 08149 ast_copy_string(a1_hash, md5secret, sizeof(a1_hash)); 08150 else { 08151 char a1[256]; 08152 snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret); 08153 ast_md5_hash(a1_hash, a1); 08154 } 08155 08156 /* compute the expected response to compare with what we received */ 08157 { 08158 char a2[256]; 08159 char a2_hash[256]; 08160 char resp[256]; 08161 08162 snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text, 08163 S_OR(keys[K_URI].s, uri)); 08164 ast_md5_hash(a2_hash, a2); 08165 snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash); 08166 ast_md5_hash(resp_hash, resp); 08167 } 08168 08169 good_response = keys[K_RESP].s && 08170 !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); 08171 if (wrongnonce) { 08172 ast_string_field_build(p, randdata, "%08lx", ast_random()); 08173 if (good_response) { 08174 if (sipdebug) 08175 ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To")); 08176 /* We got working auth token, based on stale nonce . */ 08177 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE); 08178 } else { 08179 /* Everything was wrong, so give the device one more try with a new challenge */ 08180 if (sipdebug) 08181 ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To")); 08182 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE); 08183 } 08184 08185 /* Schedule auto destroy in 32 seconds */ 08186 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08187 return AUTH_CHALLENGE_SENT; 08188 } 08189 if (good_response) { 08190 append_history(p, "AuthOK", "Auth challenge succesful for %s", username); 08191 return AUTH_SUCCESSFUL; 08192 } 08193 08194 /* Ok, we have a bad username/secret pair */ 08195 /* Challenge again, and again, and again */ 08196 transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0); 08197 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 08198 08199 return AUTH_CHALLENGE_SENT; 08200 }
| static void check_pendings | ( | struct sip_pvt * | p | ) | [static] |
Check pending actions on SIP call.
Definition at line 11641 of file chan_sip.c.
References ast_clear_flag, ast_log(), ast_test_flag, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, LOG_DEBUG, option_debug, SIP_BYE, SIP_CANCEL, SIP_NEEDREINVITE, SIP_PENDINGBYE, sip_scheddestroy(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), TRUE, and XMIT_RELIABLE.
Referenced by handle_request(), and handle_response_invite().
11642 { 11643 if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 11644 /* if we can't BYE, then this is really a pending CANCEL */ 11645 if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) 11646 transmit_request(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE); 11647 /* Actually don't destroy us yet, wait for the 487 on our original 11648 INVITE, but do set an autodestruct just in case we never get it. */ 11649 else 11650 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); 11651 ast_clear_flag(&p->flags[0], SIP_PENDINGBYE); 11652 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11653 } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) { 11654 if (option_debug) 11655 ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); 11656 /* Didn't get to reinvite yet, so do it now */ 11657 transmit_reinvite_with_sdp(p); 11658 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 11659 } 11660 }
| 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 15646 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, domain::domain, and result.
Referenced by func_check_sipdomain(), get_destination(), handle_request_refer(), and register_verify().
15647 { 15648 struct domain *d; 15649 int result = 0; 15650 15651 AST_LIST_LOCK(&domain_list); 15652 AST_LIST_TRAVERSE(&domain_list, d, list) { 15653 if (strcasecmp(d->domain, domain)) 15654 continue; 15655 15656 if (len && !ast_strlen_zero(d->context)) 15657 ast_copy_string(context, d->context, len); 15658 15659 result = 1; 15660 break; 15661 } 15662 AST_LIST_UNLOCK(&domain_list); 15663 15664 return result; 15665 }
| 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 9297 of file chan_sip.c.
References check_user_full().
Referenced by handle_request_invite().
09298 { 09299 return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL); 09300 }
| 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 8983 of file chan_sip.c.
References sip_peer::accountcode, sip_user::accountcode, accountcode, sip_user::allowtransfer, sip_peer::amaflags, sip_user::amaflags, ast_apply_ha(), ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_is_shrinkable_phonenumber(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_variable_new(), ast_verbose(), ASTOBJ_REF, ASTOBJ_UNREF, AUTH_FAKE_AUTH, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, sip_peer::autoframing, sip_user::autoframing, build_contact(), sip_peer::call_limit, sip_user::call_limit, sip_peer::callgroup, sip_user::callgroup, sip_peer::callingpres, sip_user::callingpres, sip_peer::capability, sip_user::capability, sip_peer::chanvars, sip_user::chanvars, check_auth(), sip_peer::cid_name, sip_user::cid_name, cid_name, sip_peer::cid_num, sip_user::cid_num, cid_num, sip_peer::context, context, sip_user::context, debug, do_setnat(), exten, find_peer(), find_user(), sip_peer::flags, sip_user::flags, sip_peer::fullcontact, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), sip_user::ha, sip_peer::language, sip_user::language, language, sip_peer::lastms, LOG_NOTICE, sip_peer::maxcallbitrate, sip_user::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_user::md5secret, sip_peer::mohinterpret, sip_user::mohinterpret, mohinterpret, sip_peer::mohsuggest, sip_user::mohsuggest, mohsuggest, ast_variable::next, sip_peer::pickupgroup, sip_user::pickupgroup, sip_peer::prefs, sip_user::prefs, sip_peer::secret, sip_user::secret, SIP_CALL_LIMIT, sip_cancel_destroy(), sip_debug_test_addr(), sip_destroy_peer(), sip_destroy_user(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_INSECURE_INVITE, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_VIDEOSUPPORT, SIP_PKT_IGNORE, SIP_SUBSCRIBE, SIP_TRUSTRPID, sip_peer::sipoptions, sip_user::sipoptions, strsep(), sip_peer::subscribecontext, sip_user::subscribecontext, t, sip_peer::username, and username.
Referenced by check_user(), and handle_request_subscribe().
08986 { 08987 struct sip_user *user = NULL; 08988 struct sip_peer *peer; 08989 char from[256], *c; 08990 char *of; 08991 char rpid_num[50]; 08992 const char *rpid; 08993 enum check_auth_result res = AUTH_SUCCESSFUL; 08994 char *t; 08995 char calleridname[50]; 08996 int debug=sip_debug_test_addr(sin); 08997 struct ast_variable *tmpvar = NULL, *v = NULL; 08998 char *uri2 = ast_strdupa(uri); 08999 09000 /* Terminate URI */ 09001 t = uri2; 09002 while (*t && *t > 32 && *t != ';') 09003 t++; 09004 *t = '\0'; 09005 ast_copy_string(from, get_header(req, "From"), sizeof(from)); /* XXX bug in original code, overwrote string */ 09006 if (pedanticsipchecking) 09007 ast_uri_decode(from); 09008 /* XXX here tries to map the username for invite things */ 09009 memset(calleridname, 0, sizeof(calleridname)); 09010 get_calleridname(from, calleridname, sizeof(calleridname)); 09011 if (calleridname[0]) 09012 ast_string_field_set(p, cid_name, calleridname); 09013 09014 rpid = get_header(req, "Remote-Party-ID"); 09015 memset(rpid_num, 0, sizeof(rpid_num)); 09016 if (!ast_strlen_zero(rpid)) 09017 p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num)); 09018 09019 of = get_in_brackets(from); 09020 if (ast_strlen_zero(p->exten)) { 09021 t = uri2; 09022 if (!strncmp(t, "sip:", 4)) 09023 t+= 4; 09024 ast_string_field_set(p, exten, t); 09025 t = strchr(p->exten, '@'); 09026 if (t) 09027 *t = '\0'; 09028 if (ast_strlen_zero(p->our_contact)) 09029 build_contact(p); 09030 } 09031 /* save the URI part of the From header */ 09032 ast_string_field_set(p, from, of); 09033 if (strncmp(of, "sip:", 4)) { 09034 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 09035 } else 09036 of += 4; 09037 /* Get just the username part */ 09038 if ((c = strchr(of, '@'))) { 09039 char *tmp; 09040 *c = '\0'; 09041 if ((c = strchr(of, ':'))) 09042 *c = '\0'; 09043 tmp = ast_strdupa(of); 09044 /* We need to be able to handle auth-headers looking like 09045 <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43> 09046 */ 09047 tmp = strsep(&tmp, ";"); 09048 if (ast_is_shrinkable_phonenumber(tmp)) 09049 ast_shrink_phone_number(tmp); 09050 ast_string_field_set(p, cid_num, tmp); 09051 } 09052 if (ast_strlen_zero(of)) 09053 return AUTH_SUCCESSFUL; 09054 09055 if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */ 09056 user = find_user(of, 1); 09057 09058 /* Find user based on user name in the from header */ 09059 if (user && ast_apply_ha(user->ha, sin)) { 09060 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09061 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09062 /* copy channel vars */ 09063 for (v = user->chanvars ; v ; v = v->next) { 09064 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09065 tmpvar->next = p->chanvars; 09066 p->chanvars = tmpvar; 09067 } 09068 } 09069 p->prefs = user->prefs; 09070 /* Set Frame packetization */ 09071 if (p->rtp) { 09072 ast_rtp_codec_setpref(p->rtp, &p->prefs); 09073 p->autoframing = user->autoframing; 09074 } 09075 /* replace callerid if rpid found, and not restricted */ 09076 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09077 char *tmp; 09078 if (*calleridname) 09079 ast_string_field_set(p, cid_name, calleridname); 09080 tmp = ast_strdupa(rpid_num); 09081 if (ast_is_shrinkable_phonenumber(tmp)) 09082 ast_shrink_phone_number(tmp); 09083 ast_string_field_set(p, cid_num, tmp); 09084 } 09085 09086 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE) ); 09087 09088 if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09089 sip_cancel_destroy(p); 09090 ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY); 09091 ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09092 /* Copy SIP extensions profile from INVITE */ 09093 if (p->sipoptions) 09094 user->sipoptions = p->sipoptions; 09095 09096 /* If we have a call limit, set flag */ 09097 if (user->call_limit) 09098 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09099 if (!ast_strlen_zero(user->context)) 09100 ast_string_field_set(p, context, user->context); 09101 if (!ast_strlen_zero(user->cid_num) && !ast_strlen_zero(p->cid_num)) { 09102 char *tmp = ast_strdupa(user->cid_num); 09103 if (ast_is_shrinkable_phonenumber(tmp)) 09104 ast_shrink_phone_number(tmp); 09105 ast_string_field_set(p, cid_num, tmp); 09106 } 09107 if (!ast_strlen_zero(user->cid_name) && !ast_strlen_zero(p->cid_num)) 09108 ast_string_field_set(p, cid_name, user->cid_name); 09109 ast_string_field_set(p, username, user->name); 09110 ast_string_field_set(p, peername, user->name); 09111 ast_string_field_set(p, peersecret, user->secret); 09112 ast_string_field_set(p, peermd5secret, user->md5secret); 09113 ast_string_field_set(p, subscribecontext, user->subscribecontext); 09114 ast_string_field_set(p, accountcode, user->accountcode); 09115 ast_string_field_set(p, language, user->language); 09116 ast_string_field_set(p, mohsuggest, user->mohsuggest); 09117 ast_string_field_set(p, mohinterpret, user->mohinterpret); 09118 p->allowtransfer = user->allowtransfer; 09119 p->amaflags = user->amaflags; 09120 p->callgroup = user->callgroup; 09121 p->pickupgroup = user->pickupgroup; 09122 if (user->callingpres) /* User callingpres setting will override RPID header */ 09123 p->callingpres = user->callingpres; 09124 09125 /* Set default codec settings for this call */ 09126 p->capability = user->capability; /* User codec choice */ 09127 p->jointcapability = user->capability; /* Our codecs */ 09128 if (p->peercapability) /* AND with peer's codecs */ 09129 p->jointcapability &= p->peercapability; 09130 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09131 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09132 p->noncodeccapability |= AST_RTP_DTMF; 09133 else 09134 p->noncodeccapability &= ~AST_RTP_DTMF; 09135 p->jointnoncodeccapability = p->noncodeccapability; 09136 if (p->t38.peercapability) 09137 p->t38.jointcapability &= p->t38.peercapability; 09138 p->maxcallbitrate = user->maxcallbitrate; 09139 /* If we do not support video, remove video from call structure */ 09140 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09141 ast_rtp_destroy(p->vrtp); 09142 p->vrtp = NULL; 09143 } 09144 } 09145 if (user && debug) 09146 ast_verbose("Found user '%s'\n", user->name); 09147 } else { 09148 if (user) { 09149 if (!authpeer && debug) 09150 ast_verbose("Found user '%s', but fails host access\n", user->name); 09151 ASTOBJ_UNREF(user,sip_destroy_user); 09152 } 09153 user = NULL; 09154 } 09155 09156 if (!user) { 09157 /* If we didn't find a user match, check for peers */ 09158 if (sipmethod == SIP_SUBSCRIBE) 09159 /* For subscribes, match on peer name only */ 09160 peer = find_peer(of, NULL, 1); 09161 else 09162 /* Look for peer based on the IP address we received data from */ 09163 /* If peer is registered from this IP address or have this as a default 09164 IP address, this call is from the peer 09165 */ 09166 peer = find_peer(NULL, &p->recv, 1); 09167 09168 if (peer) { 09169 /* Set Frame packetization */ 09170 if (p->rtp) { 09171 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 09172 p->autoframing = peer->autoframing; 09173 } 09174 if (debug) 09175 ast_verbose("Found peer '%s'\n", peer->name); 09176 09177 /* Take the peer */ 09178 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09179 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09180 09181 /* Copy SIP extensions profile to peer */ 09182 if (p->sipoptions) 09183 peer->sipoptions = p->sipoptions; 09184 09185 /* replace callerid if rpid found, and not restricted */ 09186 if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) { 09187 char *tmp = ast_strdupa(rpid_num); 09188 if (*calleridname) 09189 ast_string_field_set(p, cid_name, calleridname); 09190 if (ast_is_shrinkable_phonenumber(tmp)) 09191 ast_shrink_phone_number(tmp); 09192 ast_string_field_set(p, cid_num, tmp); 09193 } 09194 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)); 09195 09196 ast_string_field_set(p, peersecret, peer->secret); 09197 ast_string_field_set(p, peermd5secret, peer->md5secret); 09198 ast_string_field_set(p, subscribecontext, peer->subscribecontext); 09199 ast_string_field_set(p, mohinterpret, peer->mohinterpret); 09200 ast_string_field_set(p, mohsuggest, peer->mohsuggest); 09201 if (peer->callingpres) /* Peer calling pres setting will override RPID */ 09202 p->callingpres = peer->callingpres; 09203 if (peer->maxms && peer->lastms) 09204 p->timer_t1 = peer->lastms; 09205 if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) { 09206 /* Pretend there is no required authentication */ 09207 ast_string_field_free(p, peersecret); 09208 ast_string_field_free(p, peermd5secret); 09209 } 09210 if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, ast_test_flag(req, SIP_PKT_IGNORE)))) { 09211 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 09212 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 09213 /* If we have a call limit, set flag */ 09214 if (peer->call_limit) 09215 ast_set_flag(&p->flags[0], SIP_CALL_LIMIT); 09216 ast_string_field_set(p, peername, peer->name); 09217 ast_string_field_set(p, authname, peer->name); 09218 09219 /* copy channel vars */ 09220 for (v = peer->chanvars ; v ; v = v->next) { 09221 if ((tmpvar = ast_variable_new(v->name, v->value))) { 09222 tmpvar->next = p->chanvars; 09223 p->chanvars = tmpvar; 09224 } 09225 } 09226 if (authpeer) { 09227 (*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */ 09228 } 09229 09230 if (!ast_strlen_zero(peer->username)) { 09231 ast_string_field_set(p, username, peer->username); 09232 /* Use the default username for authentication on outbound calls */ 09233 /* XXX this takes the name from the caller... can we override ? */ 09234 ast_string_field_set(p, authname, peer->username); 09235 } 09236 if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num)) { 09237 char *tmp = ast_strdupa(peer->cid_num); 09238 if (ast_is_shrinkable_phonenumber(tmp)) 09239 ast_shrink_phone_number(tmp); 09240 ast_string_field_set(p, cid_num, tmp); 09241 } 09242 if (!ast_strlen_zero(peer->cid_name) && !ast_strlen_zero(p->cid_name)) 09243 ast_string_field_set(p, cid_name, peer->cid_name); 09244 ast_string_field_set(p, fullcontact, peer->fullcontact); 09245 if (!ast_strlen_zero(peer->context)) 09246 ast_string_field_set(p, context, peer->context); 09247 ast_string_field_set(p, peersecret, peer->secret); 09248 ast_string_field_set(p, peermd5secret, peer->md5secret); 09249 ast_string_field_set(p, language, peer->language); 09250 ast_string_field_set(p, accountcode, peer->accountcode); 09251 p->amaflags = peer->amaflags; 09252 p->callgroup = peer->callgroup; 09253 p->pickupgroup = peer->pickupgroup; 09254 p->capability = peer->capability; 09255 p->prefs = peer->prefs; 09256 p->jointcapability = peer->capability; 09257 if (p->peercapability) 09258 p->jointcapability &= p->peercapability; 09259 p->maxcallbitrate = peer->maxcallbitrate; 09260 if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(p->capability & AST_FORMAT_VIDEO_MASK)) && p->vrtp) { 09261 ast_rtp_destroy(p->vrtp); 09262 p->vrtp = NULL; 09263 } 09264 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 09265 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 09266 p->noncodeccapability |= AST_RTP_DTMF; 09267 else 09268 p->noncodeccapability &= ~AST_RTP_DTMF; 09269 p->jointnoncodeccapability = p->noncodeccapability; 09270 if (p->t38.peercapability) 09271 p->t38.jointcapability &= p->t38.peercapability; 09272 } 09273 ASTOBJ_UNREF(peer, sip_destroy_peer); 09274 } else { 09275 if (debug) 09276 ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 09277 09278 /* do we allow guests? */ 09279 if (!global_allowguest) { 09280 if (global_alwaysauthreject) 09281 res = AUTH_FAKE_AUTH; /* reject with fake authorization request */ 09282 else 09283 res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ 09284 } 09285 } 09286 09287 } 09288 09289 if (user) 09290 ASTOBJ_UNREF(user, sip_destroy_user); 09291 return res; 09292 }
| static void check_via | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
check Via: header for hostname, port and rport request/answer
Definition at line 8851 of file chan_sip.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_verbose(), sip_pvt::flags, get_header(), hp, LOG_WARNING, sip_pvt::sa, sip_debug_test_pvt(), sip_nat_mode(), SIP_NAT_ROUTE, sip_real_dst(), and STANDARD_SIP_PORT.
Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_register(), and handle_request_subscribe().
08852 { 08853 char via[256]; 08854 char *c, *pt; 08855 struct hostent *hp; 08856 struct ast_hostent ahp; 08857 08858 ast_copy_string(via, get_header(req, "Via"), sizeof(via)); 08859 08860 /* Work on the leftmost value of the topmost Via header */ 08861 c = strchr(via, ','); 08862 if (c) 08863 *c = '\0'; 08864 08865 /* Check for rport */ 08866 c = strstr(via, ";rport"); 08867 if (c && (c[6] != '=')) /* rport query, not answer */ 08868 ast_set_flag(&p->flags[0], SIP_NAT_ROUTE); 08869 08870 c = strchr(via, ';'); 08871 if (c) 08872 *c = '\0'; 08873 08874 c = strchr(via, ' '); 08875 if (c) { 08876 *c = '\0'; 08877 c = ast_skip_blanks(c+1); 08878 if (strcasecmp(via, "SIP/2.0/UDP")) { 08879 ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via); 08880 return; 08881 } 08882 pt = strchr(c, ':'); 08883 if (pt) 08884 *pt++ = '\0'; /* remember port pointer */ 08885 hp = ast_gethostbyname(c, &ahp); 08886 if (!hp) { 08887 ast_log(LOG_WARNING, "'%s' is not a valid host\n", c); 08888 return; 08889 } 08890 memset(&p->sa, 0, sizeof(p->sa)); 08891 p->sa.sin_family = AF_INET; 08892 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 08893 p->sa.sin_port = htons(pt ? atoi(pt) : STANDARD_SIP_PORT); 08894 08895 if (sip_debug_test_pvt(p)) { 08896 const struct sockaddr_in *dst = sip_real_dst(p); 08897 ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p)); 08898 } 08899 } 08900 }
| 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 9739 of file chan_sip.c.
References ast_context_destroy(), ast_context_find(), AST_MAX_CONTEXT, and strsep().
09740 { 09741 char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT]; 09742 09743 while ((oldcontext = strsep(&old, "&"))) { 09744 stalecontext = '\0'; 09745 ast_copy_string(newlist, new, sizeof(newlist)); 09746 stringp = newlist; 09747 while ((newcontext = strsep(&stringp, "&"))) { 09748 if (strcmp(newcontext, oldcontext) == 0) { 09749 /* This is not the context you're looking for */ 09750 stalecontext = '\0'; 09751 break; 09752 } else if (strcmp(newcontext, oldcontext)) { 09753 stalecontext = oldcontext; 09754 } 09755 09756 } 09757 if (stalecontext) 09758 ast_context_destroy(ast_context_find(stalecontext), "SIP"); 09759 } 09760 }
| static int clear_realm_authentication | ( | struct sip_auth * | authlist | ) | [static] |
Clear realm authentication list (at reload).
Definition at line 15739 of file chan_sip.c.
References free, and sip_auth::next.
Referenced by sip_destroy_peer(), sip_do_reload(), and unload_module().
15740 { 15741 struct sip_auth *a = authlist; 15742 struct sip_auth *b; 15743 15744 while (a) { 15745 b = a; 15746 a = a->next; 15747 free(b); 15748 } 15749 15750 return 1; 15751 }
| static void clear_sip_domains | ( | void | ) | [static] |
Clear our domain list (at reload).
Definition at line 15668 of file chan_sip.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free.
Referenced by sip_do_reload(), and unload_module().
15669 { 15670 struct domain *d; 15671 15672 AST_LIST_LOCK(&domain_list); 15673 while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list))) 15674 free(d); 15675 AST_LIST_UNLOCK(&domain_list); 15676 }
| 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 10552 of file chan_sip.c.
References complete_sip_peer().
10553 { 10554 if (pos == 3) 10555 return complete_sip_peer(word, state, 0); 10556 10557 return NULL; 10558 }
| static char * complete_sip_peer | ( | const char * | word, | |
| int | state, | |||
| int | flags2 | |||
| ) | [static] |
Do completion on peer name.
Definition at line 10526 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, peerl, and result.
Referenced by complete_sip_debug_peer(), complete_sip_prune_realtime_peer(), complete_sip_show_peer(), and complete_sipnotify().
10527 { 10528 char *result = NULL; 10529 int wordlen = strlen(word); 10530 int which = 0; 10531 10532 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !result, do { 10533 /* locking of the object is not required because only the name and flags are being compared */ 10534 if (!strncasecmp(word, iterator->name, wordlen) && 10535 (!flags2 || ast_test_flag(&iterator->flags[1], flags2)) && 10536 ++which > state) 10537 result = ast_strdup(iterator->name); 10538 } while(0) ); 10539 return result; 10540 }
| 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 10620 of file chan_sip.c.
References complete_sip_peer(), and SIP_PAGE2_RTCACHEFRIENDS.
10621 { 10622 if (pos == 4) 10623 return complete_sip_peer(word, state, SIP_PAGE2_RTCACHEFRIENDS); 10624 return NULL; 10625 }
| 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 10628 of file chan_sip.c.
References complete_sip_user(), and SIP_PAGE2_RTCACHEFRIENDS.
10629 { 10630 if (pos == 4) 10631 return complete_sip_user(word, state, SIP_PAGE2_RTCACHEFRIENDS); 10632 10633 return NULL; 10634 }
| 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 10543 of file chan_sip.c.
References complete_sip_peer().
10544 { 10545 if (pos == 3) 10546 return complete_sip_peer(word, state, 0); 10547 10548 return NULL; 10549 }
| 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 10581 of file chan_sip.c.
References complete_sip_user().
10582 { 10583 if (pos == 3) 10584 return complete_sip_user(word, state, 0); 10585 10586 return NULL; 10587 }
| static char * complete_sip_user | ( | const char * | word, | |
| int | state, | |||
| int | flags2 | |||
| ) | [static] |
Do completion on user name.
Definition at line 10561 of file chan_sip.c.
References ast_strdup, ast_test_flag, ASTOBJ_CONTAINER_TRAVERSE, result, and userl.
Referenced by complete_sip_prune_realtime_user(), and complete_sip_show_user().
10562 { 10563 char *result = NULL; 10564 int wordlen = strlen(word); 10565 int which = 0; 10566 10567 ASTOBJ_CONTAINER_TRAVERSE(&userl, !result, do { 10568 /* locking of the object is not required because only the name and flags are being compared */ 10569 if (!strncasecmp(word, iterator->name, wordlen)) { 10570 if (flags2 && !ast_test_flag(&iterator->flags[1], flags2)) 10571 continue; 10572 if (++which > state) { 10573 result = ast_strdup(iterator->name); 10574 } 10575 } 10576 } while(0) ); 10577 return result; 10578 }
| 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 10507 of file chan_sip.c.
References ast_mutex_lock(), ast_strdup, iflist, and sip_pvt::next.
10508 { 10509 int which=0; 10510 struct sip_pvt *cur; 10511 char *c = NULL; 10512 int wordlen = strlen(word); 10513 10514 ast_mutex_lock(&iflock); 10515 for (cur = iflist; cur; cur = cur->next) { 10516 if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) { 10517 c = ast_strdup(cur->callid); 10518 break; 10519 } 10520 } 10521 ast_mutex_unlock(&iflock); 10522 return c; 10523 }
| static char * complete_sipnotify | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Support routine for 'sip notify' CLI.
Definition at line 10590 of file chan_sip.c.
References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.
10591 { 10592 char *c = NULL; 10593 10594 if (pos == 2) { 10595 int which = 0; 10596 char *cat = NULL; 10597 int wordlen = strlen(word); 10598 10599 /* do completion for notify type */ 10600 10601 if (!notify_types) 10602 return NULL; 10603 10604 while ( (cat = ast_category_browse(notify_types, cat)) ) { 10605 if (!strncasecmp(word, cat, wordlen) && ++which > state) { 10606 c = ast_strdup(cat); 10607 break; 10608 } 10609 } 10610 return c; 10611 } 10612 10613 if (pos > 2) 10614 return complete_sip_peer(word, state, 0); 10615 10616 return NULL; 10617 }
| 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 5379 of file chan_sip.c.
References __get_header(), add_header(), and ast_strlen_zero().
Referenced by respprep().
05380 { 05381 int start = 0; 05382 int copied = 0; 05383 for (;;) { 05384 const char *tmp = __get_header(orig, field, &start); 05385 05386 if (ast_strlen_zero(tmp)) 05387 break; 05388 /* Add what we're responding to */ 05389 add_header(req, field, tmp); 05390 copied++; 05391 } 05392 return copied ? 0 : -1; 05393 }
| 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 5368 of file chan_sip.c.
References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.
Referenced by reqprep(), and respprep().
05369 { 05370 const char *tmp = get_header(orig, field); 05371 05372 if (!ast_strlen_zero(tmp)) /* Add what we're responding to */ 05373 return add_header(req, field, tmp); 05374 ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field); 05375 return -1; 05376 }
| 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 6413 of file chan_sip.c.
References offset.
Referenced by handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), initialize_initreq(), sip_park(), and sip_park_thread().
06414 { 06415 long offset; 06416 int x; 06417 offset = ((void *)dst) - ((void *)src); 06418 /* First copy stuff */ 06419 memcpy(dst, src, sizeof(*dst)); 06420 /* Now fix pointer arithmetic */ 06421 for (x=0; x < src->headers; x++) 06422 dst->header[x] += offset; 06423 for (x=0; x < src->lines; x++) 06424 dst->line[x] += offset; 06425 dst->rlPart1 += offset; 06426 dst->rlPart2 += offset; 06427 }
| 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 5401 of file chan_sip.c.
References __get_header(), add_header(), ast_inet_ntoa(), ast_log(), ast_strlen_zero(), ast_test_flag, sip_pvt::flags, LOG_NOTICE, sip_pvt::recv, SIP_NAT, SIP_NAT_ALWAYS, and SIP_NAT_RFC3581.
Referenced by respprep().
05402 { 05403 int copied = 0; 05404 int start = 0; 05405 05406 for (;;) { 05407 char new[256]; 05408 const char *oh = __get_header(orig, field, &start); 05409 05410 if (ast_strlen_zero(oh)) 05411 break; 05412 05413 if (!copied) { /* Only check for empty rport in topmost via header */ 05414 char leftmost[256], *others, *rport; 05415 05416 /* Only work on leftmost value */ 05417 ast_copy_string(leftmost, oh, sizeof(leftmost)); 05418 others = strchr(leftmost, ','); 05419 if (others) 05420 *others++ = '\0'; 05421 05422 /* Find ;rport; (empty request) */ 05423 rport = strstr(leftmost, ";rport"); 05424 if (rport && *(rport+6) == '=') 05425 rport = NULL; /* We already have a parameter to rport */ 05426 05427 /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting) */ 05428 if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) { 05429 /* We need to add received port - rport */ 05430 char *end; 05431 05432 rport = strstr(leftmost, ";rport"); 05433 05434 if (rport) { 05435 end = strchr(rport + 1, ';'); 05436 if (end) 05437 memmove(rport, end, strlen(end) + 1); 05438 else 05439 *rport = '\0'; 05440 } 05441 05442 /* Add rport to first VIA header if requested */ 05443 snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s", 05444 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05445 ntohs(p->recv.sin_port), 05446 others ? "," : "", others ? others : ""); 05447 } else { 05448 /* We should *always* add a received to the topmost via */ 05449 snprintf(new, sizeof(new), "%s;received=%s%s%s", 05450 leftmost, ast_inet_ntoa(p->recv.sin_addr), 05451 others ? "," : "", others ? others : ""); 05452 } 05453 oh = new; /* the header to copy */ 05454 } /* else add the following via headers untouched */ 05455 add_header(req, field, oh); 05456 copied++; 05457 } 05458 if (!copied) { 05459 ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field); 05460 return -1; 05461 } 05462 return 0; 05463 }
| 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 2699 of file chan_sip.c.
References ahp, ast_get_srv(), ast_gethostbyname(), ast_log(), ast_string_field_set, ASTOBJ_UNREF, create_addr_from_peer(), find_peer(), hp, LOG_WARNING, portno, sip_pvt::recv, sip_pvt::sa, sip_destroy_peer(), STANDARD_SIP_PORT, sip_pvt::timer_t1, and sip_peer::tohost.
02700 { 02701 struct hostent *hp; 02702 struct ast_hostent ahp; 02703 struct sip_peer *p; 02704 char *port; 02705 int portno; 02706 char host[MAXHOSTNAMELEN], *hostn; 02707 char peer[256]; 02708 02709 ast_copy_string(peer, opeer, sizeof(peer)); 02710 port = strchr(peer, ':'); 02711 if (port) 02712 *port++ = '\0'; 02713 dialog->sa.sin_family = AF_INET; 02714 dialog->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 02715 p = find_peer(peer, NULL, 1); 02716 02717 if (p) { 02718 int res = create_addr_from_peer(dialog, p); 02719 ASTOBJ_UNREF(p, sip_destroy_peer); 02720 return res; 02721 } 02722 hostn = peer; 02723 portno = port ? atoi(port) : STANDARD_SIP_PORT; 02724 if (srvlookup) { 02725 char service[MAXHOSTNAMELEN]; 02726 int tportno; 02727 int ret; 02728 02729 snprintf(service, sizeof(service), "_sip._udp.%s", peer); 02730 ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service); 02731 if (ret > 0) { 02732 hostn = host; 02733 portno = tportno; 02734 } 02735 } 02736 hp = ast_gethostbyname(hostn, &ahp); 02737 if (!hp) { 02738 ast_log(LOG_WARNING, "No such host: %s\n", peer); 02739 return -1; 02740 } 02741 ast_string_field_set(dialog, tohost, peer); 02742 memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr)); 02743 dialog->sa.sin_port = htons(portno); 02744 dialog->recv = dialog->sa; 02745 return 0; 02746 }
Create address structure from peer reference. return -1 on error, 0 on success.
Definition at line 2594 of file chan_sip.c.
References sip_peer::addr, sip_peer::allowtransfer, sip_pvt::allowtransfer, ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_log(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_destroy(), ast_udptl_get_error_correction_scheme(), sip_peer::autoframing, sip_pvt::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_pvt::callgroup, t38properties::capability, sip_peer::capability, sip_pvt::capability, sip_peer::context, context, sip_peer::defaddr, do_setnat(), sip_peer::flags, sip_pvt::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, global_t38_capability, sip_request::headers, sip_pvt::initreq, t38properties::jointcapability, sip_peer::lastms, LOG_DEBUG, sip_peer::maxcallbitrate, sip_pvt::maxcallbitrate, sip_peer::maxms, sip_pvt::maxtime, sip_peer::md5secret, sip_peer::mohinterpret, mohinterpret, sip_peer::mohsuggest, mohsuggest, sip_pvt::noncodeccapability, option_debug, sip_peer::pickupgroup, sip_pvt::pickupgroup, sip_peer::prefs, sip_pvt::prefs, sip_pvt::recv, sip_pvt::rtp, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_pvt::rtptimeout, sip_peer::rtptimeout, sip_pvt::sa, sip_peer::secret, SIP_CALL_LIMIT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_NAT, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_VIDEOSUPPORT, sip_pvt::t38, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, sip_pvt::timer_t1, sip_peer::tohost, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, username, sip_peer::username, and sip_pvt::vrtp.
Referenced by create_addr(), and sip_send_mwi_to_peer().
02595 { 02596 if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) && 02597 (!peer->maxms || ((peer->lastms >= 0) && (peer->lastms <= peer->maxms)))) { 02598 dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr; 02599 dialog->recv = dialog->sa; 02600 } else 02601 return -1; 02602 02603 ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 02604 ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 02605 dialog->capability = peer->capability; 02606 if ((!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) || !(dialog->capability & AST_FORMAT_VIDEO_MASK)) && dialog->vrtp) { 02607 ast_rtp_destroy(dialog->vrtp); 02608 dialog->vrtp = NULL; 02609 } 02610 dialog->prefs = peer->prefs; 02611 if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) { 02612 dialog->t38.capability = global_t38_capability; 02613 if (dialog->udptl) { 02614 if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC ) 02615 dialog->t38.capability |= T38FAX_UDP_EC_FEC; 02616 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY ) 02617 dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 02618 else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE ) 02619 dialog->t38.capability |= T38FAX_UDP_EC_NONE; 02620 dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 02621 if (option_debug > 1) 02622 ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", dialog->t38.capability); 02623 } 02624 dialog->t38.jointcapability = dialog->t38.capability; 02625 } else if (dialog->udptl) { 02626 ast_udptl_destroy(dialog->udptl); 02627 dialog->udptl = NULL; 02628 } 02629 do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE ); 02630 02631 if (dialog->rtp) { 02632 ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 02633 ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 02634 ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout); 02635 ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout); 02636 ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive); 02637 /* Set Frame packetization */ 02638 ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs); 02639 dialog->autoframing = peer->autoframing; 02640 } 02641 if (dialog->vrtp) { 02642 ast_rtp_setdtmf(dialog->vrtp, 0); 02643 ast_rtp_setdtmfcompensate(dialog->vrtp, 0); 02644 ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout); 02645 ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout); 02646 ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive); 02647 } 02648 02649 ast_string_field_set(dialog, peername, peer->username); 02650 ast_string_field_set(dialog, authname, peer->username); 02651 ast_string_field_set(dialog, username, peer->username); 02652 ast_string_field_set(dialog, peersecret, peer->secret); 02653 ast_string_field_set(dialog, peermd5secret, peer->md5secret); 02654 ast_string_field_set(dialog, mohsuggest, peer->mohsuggest); 02655 ast_string_field_set(dialog, mohinterpret, peer->mohinterpret); 02656 ast_string_field_set(dialog, tohost, peer->tohost); 02657 ast_string_field_set(dialog, fullcontact, peer->fullcontact); 02658 if (!dialog->initreq.headers && !ast_strlen_zero(peer->fromdomain)) { 02659 char *tmpcall; 02660 char *c; 02661 tmpcall = ast_strdupa(dialog->callid); 02662 c = strchr(tmpcall, '@'); 02663 if (c) { 02664 *c = '\0'; 02665 ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain); 02666 } 02667 } 02668 if (ast_strlen_zero(dialog->tohost)) 02669 ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr)); 02670 if (!ast_strlen_zero(peer->fromdomain)) 02671 ast_string_field_set(dialog, fromdomain, peer->fromdomain); 02672 if (!ast_strlen_zero(peer->fromuser)) 02673 ast_string_field_set(dialog, fromuser, peer->fromuser); 02674 dialog->maxtime = peer->maxms; 02675 dialog->callgroup = peer->callgroup; 02676 dialog->pickupgroup = peer->pickupgroup; 02677 dialog->allowtransfer = peer->allowtransfer; 02678 /* Set timer T1 to RTT for this peer (if known by qualify=) */ 02679 /* Minimum is settable or default to 100 ms */ 02680 if (peer->maxms && peer->lastms) 02681 dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms; 02682 if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 02683 (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 02684 dialog->noncodeccapability |= AST_RTP_DTMF; 02685 else 02686 dialog->noncodeccapability &= ~AST_RTP_DTMF; 02687 ast_string_field_set(dialog, context, peer->context); 02688 dialog->rtptimeout = peer->rtptimeout; 02689 if (peer->call_limit) 02690 ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT); 02691 dialog->maxcallbitrate = peer->maxcallbitrate; 02692 02693 return 0; 02694 }
| static void destroy_association | ( | struct sip_peer * | peer | ) | [static] |
Remove registration data from realtime database or AST/DB when registration expires.
Definition at line 7567 of file chan_sip.c.
References ast_db_del(), ast_test_flag, ast_update_realtime(), sip_peer::flags, global_flags, SIP_PAGE2_IGNOREREGEXPIRE, and SIP_PAGE2_RT_FROMCONTACT.
Referenced by build_peer(), expire_register(), and parse_register_contact().
07568 { 07569 if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { 07570 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07571 ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL); 07572 else 07573 ast_db_del("SIP/Registry", peer->name); 07574 } 07575 }
| static int determine_firstline_parts | ( | struct sip_request * | req | ) | [static] |
Parse first line of incoming SIP request.
Definition at line 6455 of file chan_sip.c.
References ast_log(), sip_request::header, LOG_WARNING, sip_request::rlPart1, and sip_request::rlPart2.
Referenced by parse_request().
06456 { 06457 char *e = ast_skip_blanks(req->header[0]); /* there shouldn't be any */ 06458 06459 if (!*e) 06460 return -1; 06461 req->rlPart1 = e; /* method or protocol */ 06462 e = ast_skip_nonblanks(e); 06463 if (*e) 06464 *e++ = '\0'; 06465 /* Get URI or status code */ 06466 e = ast_skip_blanks(e); 06467 if ( !*e ) 06468 return -1; 06469 ast_trim_blanks(e); 06470 06471 if (!strcasecmp(req->rlPart1, "SIP/2.0") ) { /* We have a response */ 06472 if (strlen(e) < 3) /* status code is 3 digits */ 06473 return -1; 06474 req->rlPart2 = e; 06475 } else { /* We have a request */ 06476 if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */ 06477 ast_log(LOG_WARNING, "bogus uri in <> %s\n", e); 06478 e++; 06479 if (!*e) 06480 return -1; 06481 } 06482 req->rlPart2 = e; /* URI */ 06483 e = ast_skip_nonblanks(e); 06484 if (*e) 06485 *e++ = '\0'; 06486 e = ast_skip_blanks(e); 06487 if (strcasecmp(e, "SIP/2.0") ) { 06488 ast_log(LOG_WARNING, "Bad request protocol %s\n", e); 06489 return -1; 06490 } 06491 } 06492 return 1; 06493 }
| static void * do_monitor | ( | void * | data | ) | [static] |
The SIP monitoring thread.
Definition at line 15024 of file chan_sip.c.
References __sip_destroy(), ast_channel_trylock, ast_channel_unlock, ast_io_add(), ast_io_change(), AST_IO_IN, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_bridged(), ast_rtp_get_peer(), ast_rtp_get_rtpholdtimeout(), ast_rtp_get_rtpkeepalive(), ast_rtp_get_rtptimeout(), ast_rtp_sendcng(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtptimeout(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, ast_verbose(), FALSE, sip_pvt::flags, iflist, io, sip_pvt::lock, LOG_NOTICE, sip_pvt::next, option_verbose, sip_pvt::owner, sip_pvt::packets, sip_do_reload(), SIP_NEEDDESTROY, sipsock, sipsock_read(), t, and VERBOSE_PREFIX_1.
15025 { 15026 int res; 15027 struct sip_pvt *sip; 15028 struct sip_peer *peer = NULL; 15029 time_t t; 15030 int fastrestart = FALSE; 15031 int lastpeernum = -1; 15032 int curpeernum; 15033 int reloading; 15034 15035 /* Add an I/O event to our SIP UDP socket */ 15036 if (sipsock > -1) 15037 sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL); 15038 15039 /* From here on out, we die whenever asked */ 15040 for(;;) { 15041 /* Check for a reload request */ 15042 ast_mutex_lock(&sip_reload_lock); 15043 reloading = sip_reloading; 15044 sip_reloading = FALSE; 15045 ast_mutex_unlock(&sip_reload_lock); 15046 if (reloading) { 15047 if (option_verbose > 0) 15048 ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n"); 15049 sip_do_reload(sip_reloadreason); 15050 15051 /* Change the I/O fd of our UDP socket */ 15052 if (sipsock > -1) 15053 sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL); 15054 } 15055 /* Check for interfaces needing to be killed */ 15056 ast_mutex_lock(&iflock); 15057 restartsearch: 15058 t = time(NULL); 15059 /* don't scan the interface list if it hasn't been a reasonable period 15060 of time since the last time we did it (when MWI is being sent, we can 15061 get back to this point every millisecond or less) 15062 */ 15063 for (sip = iflist; !fastrestart && sip; sip = sip->next) { 15064 ast_mutex_lock(&sip->lock); 15065 /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */ 15066 if (sip->rtp && sip->owner && 15067 (sip->owner->_state == AST_STATE_UP) && 15068 !sip->redirip.sin_addr.s_addr) { 15069 if (sip->lastrtptx && 15070 ast_rtp_get_rtpkeepalive(sip->rtp) && 15071 (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) { 15072 /* Need to send an empty RTP packet */ 15073 sip->lastrtptx = time(NULL); 15074 ast_rtp_sendcng(sip->rtp, 0); 15075 } 15076 if (sip->lastrtprx && 15077 (ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) && 15078 (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) { 15079 /* Might be a timeout now -- see if we're on hold */ 15080 struct sockaddr_in sin; 15081 ast_rtp_get_peer(sip->rtp, &sin); 15082 if (sin.sin_addr.s_addr || 15083 (ast_rtp_get_rtpholdtimeout(sip->rtp) && 15084 (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) { 15085 /* Needs a hangup */ 15086 if (ast_rtp_get_rtptimeout(sip->rtp)) { 15087 while (sip->owner && ast_channel_trylock(sip->owner)) { 15088 ast_mutex_unlock(&sip->lock); 15089 usleep(1); 15090 ast_mutex_lock(&sip->lock); 15091 } 15092 if (sip->owner) { 15093 if (!(ast_rtp_get_bridged(sip->rtp))) { 15094 ast_log(LOG_NOTICE, 15095 "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", 15096 sip->owner->name, 15097 (long) (t - sip->lastrtprx)); 15098 /* Issue a softhangup */ 15099 ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV); 15100 } else 15101 ast_log(LOG_NOTICE, "'%s' will not be disconnected in %ld seconds because it is directly bridged to another RTP stream\n", sip->owner->name, (long) (t - sip->lastrtprx)); 15102 ast_channel_unlock(sip->owner); 15103 /* forget the timeouts for this call, since a hangup 15104 has already been requested and we don't want to 15105 repeatedly request hangups 15106 */ 15107 ast_rtp_set_rtptimeout(sip->rtp, 0); 15108 ast_rtp_set_rtpholdtimeout(sip->rtp, 0); 15109 if (sip->vrtp) { 15110 ast_rtp_set_rtptimeout(sip->vrtp, 0); 15111 ast_rtp_set_rtpholdtimeout(sip->vrtp, 0); 15112 } 15113 } 15114 } 15115 } 15116 } 15117 } 15118 /* If we have sessions that needs to be destroyed, do it now */ 15119 if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && 15120 !sip->owner) { 15121 ast_mutex_unlock(&sip->lock); 15122 __sip_destroy(sip, 1); 15123 goto restartsearch; 15124 } 15125 ast_mutex_unlock(&sip->lock); 15126 } 15127 ast_mutex_unlock(&iflock); 15128 15129 pthread_testcancel(); 15130 /* Wait for sched or io */ 15131 res = ast_sched_wait(sched); 15132 if ((res < 0) || (res > 1000)) 15133 res = 1000; 15134 /* If we might need to send more mailboxes, don't wait long at all.*/ 15135 if (fastrestart) 15136 res = 1; 15137 res = ast_io_wait(io, res); 15138 if (option_debug && res > 20) 15139 ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res); 15140 ast_mutex_lock(&monlock); 15141 if (res >= 0) { 15142 res = ast_sched_runq(sched); 15143 if (option_debug && res >= 20) 15144 ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res); 15145 } 15146 15147 /* Send MWI notifications to peers - static and cached realtime peers */ 15148 t = time(NULL); 15149 fastrestart = FALSE; 15150 curpeernum = 0; 15151 peer = NULL; 15152 /* Find next peer that needs mwi */ 15153 ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do { 15154 if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) { 15155 fastrestart = TRUE; 15156 lastpeernum = curpeernum; 15157 peer = ASTOBJ_REF(iterator); 15158 }; 15159 curpeernum++; 15160 } while (0) 15161 ); 15162 /* Send MWI to the peer */ 15163 if (peer) { 15164 ASTOBJ_WRLOCK(peer); 15165 sip_send_mwi_to_peer(peer); 15166 ASTOBJ_UNLOCK(peer); 15167 ASTOBJ_UNREF(peer,sip_destroy_peer); 15168 } else { 15169 /* Reset where we come from */ 15170 lastpeernum = -1; 15171 } 15172 ast_mutex_unlock(&monlock); 15173 } 15174 /* Never reached */ 15175 return NULL; 15176 15177 }
| 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 11088 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().
11089 { 11090 char digest[1024]; 11091 11092 if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options)))) 11093 return -2; 11094 11095 p->authtries++; 11096 if (option_debug > 1) 11097 ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text); 11098 memset(digest, 0, sizeof(digest)); 11099 if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) { 11100 /* No way to authenticate */ 11101 return -1; 11102 } 11103 /* Now we have a reply digest */ 11104 p->options->auth = digest; 11105 p->options->authheader = respheader; 11106 return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 11107 }
| 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 11067 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().
11068 { 11069 char digest[1024]; 11070 p->authtries++; 11071 memset(digest,0,sizeof(digest)); 11072 if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) { 11073 /* There's nothing to use for authentication */ 11074 /* No digest challenge in request */ 11075 if (sip_debug_test_pvt(p) && p->registry) 11076 ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname); 11077 /* No old challenge */ 11078 return -1; 11079 } 11080 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 11081 append_history(p, "RegistryAuth", "Try: %d", p->authtries); 11082 if (sip_debug_test_pvt(p) && p->registry) 11083 ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname); 11084 return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 11085 }
| static void do_setnat | ( | struct sip_pvt * | p, | |
| int | natflags | |||
| ) | [static] |
Set nat mode on the various data sockets.
Definition at line 2570 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().
02571 { 02572 const char *mode = natflags ? "On" : "Off"; 02573 02574 if (p->rtp) { 02575 if (option_debug) 02576 ast_log(LOG_DEBUG, "Setting NAT on RTP to %s\n", mode); 02577 ast_rtp_setnat(p->rtp, natflags); 02578 } 02579 if (p->vrtp) { 02580 if (option_debug) 02581 ast_log(LOG_DEBUG, "Setting NAT on VRTP to %s\n", mode); 02582 ast_rtp_setnat(p->vrtp, natflags); 02583 } 02584 if (p->udptl) { 02585 if (option_debug) 02586 ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %s\n", mode); 02587 ast_udptl_setnat(p->udptl, natflags); 02588 } 02589 }
| static int does_peer_need_mwi | ( | struct sip_peer * | peer | ) | [static] |
Check whether peer needs a new MWI notification check.
Definition at line 15003 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.
15004 { 15005 time_t t = time(NULL); 15006 15007 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) && 15008 !peer->mwipvt) { /* We don't have a subscription */ 15009 peer->lastmsgcheck = t; /* Reset timer */ 15010 return FALSE; 15011 } 15012 15013 if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global_mwitime) 15014 return TRUE; 15015 15016 return FALSE; 15017 }
| static const char * domain_mode_to_text | ( | const enum domain_mode | mode | ) | [static] |
Print domain mode to cli.
Definition at line 9928 of file chan_sip.c.
References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.
Referenced by sip_show_domains().
09929 { 09930 switch (mode) { 09931 case SIP_DOMAIN_AUTO: 09932 return "[Automatic]"; 09933 case SIP_DOMAIN_CONFIG: 09934 return "[Configured]"; 09935 } 09936 09937 return ""; 09938 }
| static const char * dtmfmode2str | ( | int | mode | ) | const [static] |
Convert DTMF mode to printable string.
Definition at line 9708 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().
09709 { 09710 switch (mode) { 09711 case SIP_DTMF_RFC2833: 09712 return "rfc2833"; 09713 case SIP_DTMF_INFO: 09714 return "info"; 09715 case SIP_DTMF_INBAND: 09716 return "inband"; 09717 case SIP_DTMF_AUTO: 09718 return "auto"; 09719 } 09720 return "<error>"; 09721 }
| static int expire_register | ( | void * | data | ) | [static] |
Expire registration of SIP peer.
Definition at line 7578 of file chan_sip.c.
References sip_peer::addr, ast_device_state_changed(), ast_test_flag, ASTOBJ_CONTAINER_UNLINK, ASTOBJ_UNREF, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, FALSE, sip_peer::flags, manager_event(), peerl, register_peer_exten(), sip_destroy_peer(), SIP_PAGE2_RTAUTOCLEAR, and SIP_PAGE2_SELFDESTRUCT.
Referenced by parse_register_contact(), and reg_source_db().
07579 { 07580 struct sip_peer *peer = data; 07581 07582 if (!peer) /* Hmmm. We have no peer. Weird. */ 07583 return 0; 07584 07585 memset(&peer->addr, 0, sizeof(peer->addr)); 07586 07587 destroy_association(peer); /* remove registration data from storage */ 07588 07589 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 07590 register_peer_exten(peer, FALSE); /* Remove regexten */ 07591 peer->expire = -1; 07592 ast_device_state_changed("SIP/%s", peer->name); 07593 07594 /* Do we need to release this peer from memory? 07595 Only for realtime peers and autocreated peers 07596 */ 07597 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT) || 07598 ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 07599 peer = ASTOBJ_CONTAINER_UNLINK(&peerl, peer); /* Remove from peer list */ 07600 ASTOBJ_UNREF(peer, sip_destroy_peer); /* Remove from memory */ 07601 } 07602 07603 return 0; 07604 }
| static void extract_uri | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Check Contact: URI of SIP message.
Definition at line 6545 of file chan_sip.c.
References ast_string_field_set, ast_strlen_zero(), get_header(), get_in_brackets(), and strsep().
Referenced by handle_request(), and handle_request_invite().
06546 { 06547 char stripped[BUFSIZ]; 06548 char *c; 06549 06550 ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped)); 06551 c = get_in_brackets(stripped); 06552 c = strsep(&c, ";"); /* trim ; and beyond */ 06553 if (!ast_strlen_zero(c)) 06554 ast_string_field_set(p, uri, c); 06555 }
| 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 3969 of file chan_sip.c.
References aliases.
03970 { 03971 /*! \brief Structure for conversion between compressed SIP and "normal" SIP */ 03972 static const struct cfalias { 03973 char * const fullname; 03974 char * const shortname; 03975 } aliases[] = { 03976 { "Content-Type", "c" }, 03977 { "Content-Encoding", "e" }, 03978 { "From", "f" }, 03979 { "Call-ID", "i" }, 03980 { "Contact", "m" }, 03981 { "Content-Length", "l" }, 03982 { "Subject", "s" }, 03983 { "To", "t" }, 03984 { "Supported", "k" }, 03985 { "Refer-To", "r" }, 03986 { "Referred-By", "b" }, 03987 { "Allow-Events", "u" }, 03988 { "Event", "o" }, 03989 { "Via", "v" }, 03990 { "Accept-Contact", "a" }, 03991 { "Reject-Contact", "j" }, 03992 { "Request-Disposition", "d" }, 03993 { "Session-Expires", "x" }, 03994 { "Identity", "y" }, 03995 { "Identity-Info", "n" }, 03996 }; 03997 int x; 03998 03999 for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 04000 if (!strcasecmp(aliases[x].fullname, name)) 04001 return aliases[x].shortname; 04002 04003 return _default; 04004 }
| 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 4328 of file chan_sip.c.
References ast_log(), ast_mutex_lock(), ast_set_flag, ast_strlen_zero(), FALSE, get_header(), gettag(), iflist, LOG_DEBUG, sip_request::method, sip_pvt::next, option_debug, SIP_PKT_WITH_TOTAG, SIP_REGISTER, SIP_RESPONSE, and sip_pvt::tag.
Referenced by sipsock_read().
04329 { 04330 struct sip_pvt *p = NULL; 04331 char *tag = ""; /* note, tag is never NULL */ 04332 char totag[128]; 04333 char fromtag[128]; 04334 const char *callid = get_header(req, "Call-ID"); 04335 const char *from = get_header(req, "From"); 04336 const char *to = get_header(req, "To"); 04337 const char *cseq = get_header(req, "Cseq"); 04338 04339 /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */ 04340 /* get_header always returns non-NULL so we must use ast_strlen_zero() */ 04341 if (ast_strlen_zero(callid) || ast_strlen_zero(to) || 04342 ast_strlen_zero(from) || ast_strlen_zero(cseq)) 04343 return NULL; /* Invalid packet */ 04344 04345 if (pedanticsipchecking) { 04346 /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy 04347 we need more to identify a branch - so we have to check branch, from 04348 and to tags to identify a call leg. 04349 For Asterisk to behave correctly, you need to turn on pedanticsipchecking 04350 in sip.conf 04351 */ 04352 if (gettag(req, "To", totag, sizeof(totag))) 04353 ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */ 04354 gettag(req, "From", fromtag, sizeof(fromtag)); 04355 04356 tag = (req->method == SIP_RESPONSE) ? totag : fromtag; 04357 04358 if (option_debug > 4 ) 04359 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); 04360 } 04361 04362 ast_mutex_lock(&iflock); 04363 for (p = iflist; p; p = p->next) { 04364 /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */ 04365 int found = FALSE; 04366 if (ast_strlen_zero(p->callid)) 04367 continue; 04368 if (req->method == SIP_REGISTER) 04369 found = (!strcmp(p->callid, callid)); 04370 else 04371 found = (!strcmp(p->callid, callid) && 04372 (!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ; 04373 04374 if (option_debug > 4) 04375 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); 04376 04377 /* If we get a new request within an existing to-tag - check the to tag as well */ 04378 if (pedanticsipchecking && found && req->method != SIP_RESPONSE) { /* SIP Request */ 04379 if (p->tag[0] == '\0' && totag[0]) { 04380 /* We have no to tag, but they have. Wrong dialog */ 04381 found = FALSE; 04382 } else if (totag[0]) { /* Both have tags, compare them */ 04383 if (strcmp(totag, p->tag)) { 04384 found = FALSE; /* This is not our packet */ 04385 } 04386 } 04387 if (!found && option_debug > 4) 04388 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); 04389 } 04390 04391 04392 if (found) { 04393 /* Found the call */ 04394 ast_mutex_unlock(&iflock); 04395 ast_mutex_lock(&p->lock); 04396 return p; 04397 } 04398 } 04399 ast_mutex_unlock(&iflock); 04400 04401 /* See if the method is capable of creating a dialog */ 04402 if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) { 04403 if (intended_method == SIP_REFER) { 04404 /* We do support REFER, but not outside of a dialog yet */ 04405 transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)"); 04406 } else if (intended_method == SIP_NOTIFY) { 04407 /* We do not support out-of-dialog NOTIFY either, 04408 like voicemail notification, so cancel that early */ 04409 transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); 04410 } else { 04411 /* Ok, time to create a new SIP dialog object, a pvt */ 04412 if ((p = sip_alloc(callid, sin, 1, intended_method))) { 04413 /* Ok, we've created a dialog, let's go and process it */ 04414 ast_mutex_lock(&p->lock); 04415 } else { 04416 /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not 04417 getting a dialog from sip_alloc. 04418 04419 Without a dialog we can't retransmit and handle ACKs and all that, but at least 04420 send an error message. 04421 04422 Sorry, we apologize for the inconvienience 04423 */ 04424 transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error"); 04425 if (option_debug > 3) 04426 ast_log(LOG_DEBUG, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n"); 04427 } 04428 } 04429 return p; 04430 } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) { 04431 /* A method we do not support, let's take it on the volley */ 04432 transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented"); 04433 } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) { 04434 /* This is a request outside of a dialog that we don't know about 04435 ...never reply to an ACK! 04436 */ 04437 transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist"); 04438 } 04439 /* We do not respond to responses for dialogs that we don't know about, we just drop 04440 the session quickly */ 04441 04442 return p; 04443 }
| 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 2211 of file chan_sip.c.
References s.
Referenced by get_in_brackets().
02212 { 02213 char last_char = '\0'; 02214 const char *s; 02215 for (s = start; *s && s != lim; last_char = *s++) { 02216 if (*s == '"' && last_char != '\\') 02217 break; 02218 } 02219 return s; 02220 }
| static struct sip_peer * find_peer | ( | const char * | peer, | |
| struct sockaddr_in * | sin, | |||
| int | realtime | |||
| ) | [static] |
Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name.
Definition at line 2482 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, name, peerl, realtime_peer(), and sip_addrcmp().
02483 { 02484 struct sip_peer *p = NULL; 02485 02486 if (peer) 02487 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 02488 else 02489 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); 02490 02491 if (!p && realtime) 02492 p = realtime_peer(peer, sin); 02493 02494 return p; 02495 }
| static struct sip_auth * find_realm_authentication | ( | struct sip_auth * | authlist, | |
| const char * | realm | |||
| ) | [static] |
Find authentication for a specific realm.
Definition at line 15754 of file chan_sip.c.
References sip_auth::next, and sip_auth::realm.
Referenced by build_reply_digest().
15755 { 15756 struct sip_auth *a; 15757 15758 for (a = authlist; a; a = a->next) { 15759 if (!strcasecmp(a->realm, realm)) 15760 break; 15761 } 15762 15763 return a; 15764 }
| 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 4649 of file chan_sip.c.
References ast_strdupa, ast_strlen_zero(), FALSE, get_header(), sip_request::line, sip_request::lines, sip_request::sdp_end, sip_request::sdp_start, strcasestr(), and TRUE.
Referenced by handle_request(), handle_request_invite(), handle_response(), and handle_response_invite().
04650 { 04651 const char *content_type; 04652 const char *search; 04653 char *boundary; 04654 unsigned int x; 04655 int boundaryisquoted = FALSE; 04656 04657 content_type = get_header(req, "Content-Type"); 04658 04659 /* if the body contains only SDP, this is easy */ 04660 if (!strcasecmp(content_type, "application/sdp")) { 04661 req->sdp_start = 0; 04662 req->sdp_end = req->lines; 04663 return 1; 04664 } 04665 04666 /* if it's not multipart/mixed, there cannot be an SDP */ 04667 if (strncasecmp(content_type, "multipart/mixed", 15)) 04668 return 0; 04669 04670 /* if there is no boundary marker, it's invalid */ 04671 if (!(search = strcasestr(content_type, ";boundary="))) 04672 return 0; 04673 04674 search += 10; 04675 if (ast_strlen_zero(search)) 04676 return 0; 04677 04678 /* If the boundary is quoted with ", remove quote */ 04679 if (*search == '\"') { 04680 search++; 04681 boundaryisquoted = TRUE; 04682 } 04683 04684 /* make a duplicate of the string, with two extra characters 04685 at the beginning */ 04686 boundary = ast_strdupa(search - 2); 04687 boundary[0] = boundary[1] = '-'; 04688 04689 /* Remove final quote */ 04690 if (boundaryisquoted) 04691 boundary[strlen(boundary) - 1] = '\0'; 04692 04693 /* search for the boundary marker, but stop when there are not enough 04694 lines left for it, the Content-Type header and at least one line of 04695 body */ 04696 for (x = 0; x < (req->lines - 2); x++) { 04697 if (!strncasecmp(req->line[x], boundary, strlen(boundary)) && 04698 !strcasecmp(req->line[x + 1], "Content-Type: application/sdp")) { 04699 x += 2; 04700 req->sdp_start = x; 04701 04702 /* search for the end of the body part */ 04703 for ( ; x < req->lines; x++) { 04704 if (!strncasecmp(req->line[x], boundary, strlen(boundary))) 04705 break; 04706 } 04707 req->sdp_end = x; 04708 return 1; 04709 } 04710 } 04711 04712 return 0; 04713 }
| static int find_sip_method | ( | const char * | msg | ) | [static] |
find_sip_method: Find SIP method from header
Definition at line 1655 of file chan_sip.c.
References ast_strlen_zero(), method_match(), and sip_methods.
Referenced by __sip_pretend_ack(), handle_response(), and sipsock_read().
01656 { 01657 int i, res = 0; 01658 01659 if (ast_strlen_zero(msg)) 01660 return 0; 01661 for (i = 1; i < (sizeof(sip_methods) / sizeof(sip_methods[0])) && !res; i++) { 01662 if (method_match(i, msg)) 01663 res = sip_methods[i].id; 01664 } 01665 return res; 01666 }
| static struct cfsubscription_types * find_subscription_type | ( | enum subscriptiontype | subtype | ) | [static] |
Find subscription type in array.
Definition at line 10422 of file chan_sip.c.
References subscription_types, and type.
Referenced by transmit_state_notify().
10423 { 10424 int i; 10425 10426 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10427 if (subscription_types[i].type == subtype) { 10428 return &subscription_types[i]; 10429 } 10430 } 10431 return &subscription_types[0]; 10432 }
| 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 2561 of file chan_sip.c.
References ASTOBJ_CONTAINER_FIND, realtime_user(), and userl.
02562 { 02563 struct sip_user *u = ASTOBJ_CONTAINER_FIND(&userl, name); 02564 if (!u && realtime) 02565 u = realtime_user(name); 02566 return u; 02567 }
| static void free_old_route | ( | struct sip_route * | route | ) | [static] |
Remove route from route list.
Definition at line 7910 of file chan_sip.c.
References free, and sip_route::next.
Referenced by __sip_destroy(), and build_route().
07911 { 07912 struct sip_route *next; 07913 07914 while (route) { 07915 next = route->next; 07916 free(route); 07917 route = next; 07918 } 07919 }
| 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 11414 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING.
11415 { 11416 if (ast_strlen_zero(data)) { 11417 ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n"); 11418 return -1; 11419 } 11420 if (check_sip_domain(data, NULL, 0)) 11421 ast_copy_string(buf, data, len); 11422 else 11423 buf[0] = '\0'; 11424 return 0; 11425 }
| 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 11350 of file chan_sip.c.
References __get_header(), AST_APP_ARG, ast_channel_lock, ast_channel_unlock, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), sip_request::header, sip_pvt::initreq, LOG_WARNING, sip_tech, sip_tech_info, ast_channel::tech, and ast_channel::tech_pvt.
11351 { 11352 struct sip_pvt *p; 11353 const char *content = NULL; 11354 AST_DECLARE_APP_ARGS(args, 11355 AST_APP_ARG(header); 11356 AST_APP_ARG(number); 11357 ); 11358 int i, number, start = 0; 11359 11360 if (ast_strlen_zero(data)) { 11361 ast_log(LOG_WARNING, "This function requires a header name.\n"); 11362 return -1; 11363 } 11364 11365 ast_channel_lock(chan); 11366 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11367 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11368 ast_channel_unlock(chan); 11369 return -1; 11370 } 11371 11372 AST_STANDARD_APP_ARGS(args, data); 11373 if (!args.number) { 11374 number = 1; 11375 } else { 11376 sscanf(args.number, "%d", &number); 11377 if (number < 1) 11378 number = 1; 11379 } 11380 11381 p = chan->tech_pvt; 11382 11383 /* If there is no private structure, this channel is no longer alive */ 11384 if (!p) { 11385 ast_channel_unlock(chan); 11386 return -1; 11387 } 11388 11389 for (i = 0; i < number; i++) 11390 content = __get_header(&p->initreq, args.header, &start); 11391 11392 if (ast_strlen_zero(content)) { 11393 ast_channel_unlock(chan); 11394 return -1; 11395 } 11396 11397 ast_copy_string(buf, content, len); 11398 ast_channel_unlock(chan); 11399 11400 return 0; 11401 }
| 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 11529 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), LOG_WARNING, sip_pvt::recv, sip_pvt::sa, sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, ast_channel::tech, and ast_channel::tech_pvt.
11530 { 11531 struct sip_pvt *p; 11532 11533 *buf = 0; 11534 11535 if (!data) { 11536 ast_log(LOG_WARNING, "This function requires a parameter name.\n"); 11537 return -1; 11538 } 11539 11540 ast_channel_lock(chan); 11541 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 11542 ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n"); 11543 ast_channel_unlock(chan); 11544 return -1; 11545 } 11546 11547 p = chan->tech_pvt; 11548 11549 /* If there is no private structure, this channel is no longer alive */ 11550 if (!p) { 11551 ast_channel_unlock(chan); 11552 return -1; 11553 } 11554 11555 if (!strcasecmp(data, "peerip")) { 11556 ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len); 11557 } else if (!strcasecmp(data, "recvip")) { 11558 ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len); 11559 } else if (!strcasecmp(data, "from")) { 11560 ast_copy_string(buf, p->from, len); 11561 } else if (!strcasecmp(data, "uri")) { 11562 ast_copy_string(buf, p->uri, len); 11563 } else if (!strcasecmp(data, "useragent")) { 11564 ast_copy_string(buf, p->useragent, len); 11565 } else if (!strcasecmp(data, "peername")) { 11566 ast_copy_string(buf, p->peername, len); 11567 } else if (!strcasecmp(data, "t38passthrough")) { 11568 if (p->t38.state == T38_DISABLED) 11569 ast_copy_string(buf, "0", sizeof("0")); 11570 else /* T38 is offered or enabled in this call */ 11571 ast_copy_string(buf, "1", sizeof("1")); 11572 } else { 11573 ast_channel_unlock(chan); 11574 return -1; 11575 } 11576 ast_channel_unlock(chan); 11577 11578 return 0; 11579 }
| 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 11439 of file chan_sip.c.
References sip_peer::accountcode, sip_peer::addr, ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_peer::capability, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::expire, find_peer(), sip_peer::flags, sip_peer::inUse, sip_peer::language, sip_peer::mailbox, peer_status(), sip_peer::prefs, sip_peer::regexten, sip_destroy_peer(), SIP_PAGE2_DYNAMIC, strsep(), and sip_peer::useragent.
11440 { 11441 struct sip_peer *peer; 11442 char *colname; 11443 11444 if ((colname = strchr(data, ':'))) /*! \todo Will be deprecated after 1.4 */ 11445 *colname++ = '\0'; 11446 else if ((colname = strchr(data, '|'))) 11447 *colname++ = '\0'; 11448 else 11449 colname = "ip"; 11450 11451 if (!(peer = find_peer(data, NULL, 1))) 11452 return -1; 11453 11454 if (!strcasecmp(colname, "ip")) { 11455 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 11456 } else if (!strcasecmp(colname, "status")) { 11457 peer_status(peer, buf, len); 11458 } else if (!strcasecmp(colname, "language")) { 11459 ast_copy_string(buf, peer->language, len); 11460 } else if (!strcasecmp(colname, "regexten")) { 11461 ast_copy_string(buf, peer->regexten, len); 11462 } else if (!strcasecmp(colname, "limit")) { 11463 snprintf(buf, len, "%d", peer->call_limit); 11464 } else if (!strcasecmp(colname, "curcalls")) { 11465 snprintf(buf, len, "%d", peer->inUse); 11466 } else if (!strcasecmp(colname, "accountcode")) { 11467 ast_copy_string(buf, peer->accountcode, len); 11468 } else if (!strcasecmp(colname, "useragent")) { 11469 ast_copy_string(buf, peer->useragent, len); 11470 } else if (!strcasecmp(colname, "mailbox")) { 11471 ast_copy_string(buf, peer->mailbox, len); 11472 } else if (!strcasecmp(colname, "context")) { 11473 ast_copy_string(buf, peer->context, len); 11474 } else if (!strcasecmp(colname, "expire")) { 11475 snprintf(buf, len, "%d", peer->expire); 11476 } else if (!strcasecmp(colname, "dynamic")) { 11477 ast_copy_string(buf, (ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len); 11478 } else if (!strcasecmp(colname, "callerid_name")) { 11479 ast_copy_string(buf, peer->cid_name, len); 11480 } else if (!strcasecmp(colname, "callerid_num")) { 11481 ast_copy_string(buf, peer->cid_num, len); 11482 } else if (!strcasecmp(colname, "codecs")) { 11483 ast_getformatname_multiple(buf, len -1, peer->capability); 11484 } else if (!strncasecmp(colname, "codec[", 6)) { 11485 char *codecnum; 11486 int index = 0, codec = 0; 11487 11488 codecnum = colname + 6; /* move past the '[' */ 11489 codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */ 11490 index = atoi(codecnum); 11491 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 11492 ast_copy_string(buf, ast_getformatname(codec), len); 11493 } 11494 } 11495 11496 ASTOBJ_UNREF(peer, sip_destroy_peer); 11497 11498 return 0; 11499 }
| static char * generate_random_string | ( | char * | buf, | |
| size_t | size | |||
| ) | [static] |
Generate 32 byte random string for callid's etc.
Definition at line 4162 of file chan_sip.c.
References ast_random().
Referenced by build_callid_pvt(), and build_callid_registry().
04163 { 04164 long val[4]; 04165 int x; 04166 04167 for (x=0; x<4; x++) 04168 val[x] = ast_random(); 04169 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 04170 04171 return buf; 04172 }
| 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 8796 of file chan_sip.c.
References ast_canmatch_extension(), ast_exists_extension(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, ast_channel::macrocontext, option_debug, sip_pvt::owner, pbx_builtin_getvar_helper(), sip_pvt::refer, sip_refer::refer_call, sip_refer::refer_contact, sip_refer::refer_to, sip_refer::refer_to_domain, sip_refer::referred_by, S_OR, and sip_debug_test_pvt().
Referenced by handle_request_bye().
08797 { 08798 char tmp[256] = "", *c, *a; 08799 struct sip_request *req = oreq ? oreq : &p->initreq; 08800 struct sip_refer *referdata = p->refer; 08801 const char *transfer_context = NULL; 08802 08803 ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp)); 08804 c = get_in_brackets(tmp); 08805 08806 if (pedanticsipchecking) 08807 ast_uri_decode(c); 08808 08809 if (strncmp(c, "sip:", 4)) { 08810 ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 08811 return -1; 08812 } 08813 c += 4; 08814 if ((a = strchr(c, ';'))) /* Remove arguments */ 08815 *a = '\0'; 08816 08817 if ((a = strchr(c, '@'))) { /* Separate Domain */ 08818 *a++ = '\0'; 08819 ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain)); 08820 } 08821 08822 if (sip_debug_test_pvt(p)) 08823 ast_verbose("Looking for %s in %s\n", c, p->context); 08824 08825 if (p->owner) /* Mimic behaviour in res_features.c */ 08826 transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); 08827 08828 /* By default, use the context in the channel sending the REFER */ 08829 if (ast_strlen_zero(transfer_context)) { 08830 transfer_context = S_OR(p->owner->macrocontext, 08831 S_OR(p->context, default_context)); 08832 } 08833 if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { 08834 /* This is a blind transfer */ 08835 if (option_debug) 08836 ast_log(LOG_DEBUG,"SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); 08837 ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to)); 08838 ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by)); 08839 ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact)); 08840 referdata->refer_call = NULL; 08841 /* Set new context */ 08842 ast_string_field_set(p, context, transfer_context); 08843 return 0; 08844 } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) { 08845 return 1; 08846 } 08847 08848 return -1; 08849 }
| static char* get_body | ( | struct sip_request * | req, | |
| char * | name | |||
| ) | [static] |
Get a specific line from the message body.
Definition at line 3953 of file chan_sip.c.
References get_body_by_line(), len, sip_request::line, and sip_request::lines.
Referenced by handle_request_info().
03954 { 03955 int x; 03956 int len = strlen(name); 03957 char *r; 03958 03959 for (x = 0; x < req->lines; x++) { 03960 r = get_body_by_line(req->line[x], name, len); 03961 if (r[0] != '\0') 03962 return r; 03963 } 03964 03965 return ""; 03966 }
| 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 3919 of file chan_sip.c.
Referenced by get_body(), and get_sdp_iterate().
03920 { 03921 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') 03922 return ast_skip_blanks(line + nameLen + 1); 03923 03924 return ""; 03925 }
| static char * get_calleridname | ( | const char * | input, | |
| char * | output, | |||
| size_t | outputsize | |||
| ) | [static] |
Get caller id name from SIP headers.
Definition at line 8903 of file chan_sip.c.
Referenced by check_user_full().
08904 { 08905 const char *end = strchr(input,'<'); /* first_bracket */ 08906 const char *tmp = strchr(input,'"'); /* first quote */ 08907 int bytes = 0; 08908 int maxbytes = outputsize - 1; 08909 08910 if (!end || end == input) /* we require a part in brackets */ 08911 return NULL; 08912 08913 end--; /* move just before "<" */ 08914 08915 if (tmp && tmp <= end) { 08916 /* The quote (tmp) precedes the bracket (end+1). 08917 * Find the matching quote and return the content. 08918 */ 08919 end = strchr(tmp+1, '"'); 08920 if (!end) 08921 return NULL; 08922 bytes = (int) (end - tmp); 08923 /* protect the output buffer */ 08924 if (bytes > maxbytes) 08925 bytes = maxbytes; 08926 ast_copy_string(output, tmp + 1, bytes); 08927 } else { 08928 /* No quoted string, or it is inside brackets. */ 08929 /* clear the empty characters in the begining*/ 08930 input = ast_skip_blanks(input); 08931 /* clear the empty characters in the end */ 08932 while(*end && *end < 33 && end > input) 08933 end--; 08934 if (end >= input) { 08935 bytes = (int) (end - input) + 2; 08936 /* protect the output buffer */ 08937 if (bytes > maxbytes) 08938 bytes = maxbytes; 08939 ast_copy_string(output, input, bytes); 08940 } else 08941 return NULL; 08942 } 08943 return output; 08944 }
| 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 8470 of file chan_sip.c.
References ast_canmatch_extension(), ast_exists_extension(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), check_sip_domain(), context, exten, get_header(), get_in_brackets(), global_flags, sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, sip_request::method, option_debug, sip_request::rlPart2, sip_debug_test_pvt(), SIP_INVITE, sip_methods, SIP_PAGE2_ALLOWOVERLAP, SIP_REFER, strsep(), and cfsip_methods::text.
Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe().
08471 { 08472 char tmp[256] = "", *uri, *a; 08473 char tmpf[256] = "", *from; 08474 struct sip_request *req; 08475 char *colon; 08476 08477 req = oreq; 08478 if (!req) 08479 req = &p->initreq; 08480 08481 /* Find the request URI */ 08482 if (req->rlPart2) 08483 ast_copy_string(tmp, req->rlPart2, sizeof(tmp)); 08484 08485 if (pedanticsipchecking) 08486 ast_uri_decode(tmp); 08487 08488 uri = get_in_brackets(tmp); 08489 08490 if (strncmp(uri, "sip:", 4)) { 08491 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 08492 return -1; 08493 } 08494 uri += 4; 08495 08496 /* Now find the From: caller ID and name */ 08497 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 08498 if (!ast_strlen_zero(tmpf)) { 08499 if (pedanticsipchecking) 08500 ast_uri_decode(tmpf); 08501 from = get_in_brackets(tmpf); 08502 } else { 08503 from = NULL; 08504 } 08505 08506 if (!ast_strlen_zero(from)) { 08507 if (strncmp(from, "sip:", 4)) { 08508 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 08509 return -1; 08510 } 08511 from += 4; 08512 if ((a = strchr(from, '@'))) 08513 *a++ = '\0'; 08514 else 08515 a = from; /* just a domain */ 08516 from = strsep(&from, ";"); /* Remove userinfo options */ 08517 a = strsep(&a, ";"); /* Remove URI options */ 08518 ast_string_field_set(p, fromdomain, a); 08519 } 08520 08521 /* Skip any options and find the domain */ 08522 08523 /* Get the target domain */ 08524 if ((a = strchr(uri, '@'))) { 08525 *a++ = '\0'; 08526 } else { /* No username part */ 08527 a = uri; 08528 uri = "s"; /* Set extension to "s" */ 08529 } 08530 colon = strchr(a, ':'); /* Remove :port */ 08531 if (colon) 08532 *colon = '\0'; 08533 08534 uri = strsep(&uri, ";"); /* Remove userinfo options */ 08535 a = strsep(&a, ";"); /* Remove URI options */ 08536 08537 ast_string_field_set(p, domain, a); 08538 08539 if (!AST_LIST_EMPTY(&domain_list)) { 08540 char domain_context[AST_MAX_EXTENSION]; 08541 08542 domain_context[0] = '\0'; 08543 if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) { 08544 if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) { 08545 if (option_debug) 08546 ast_log(LOG_DEBUG, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain); 08547 return -2; 08548 } 08549 } 08550 /* If we have a context defined, overwrite the original context */ 08551 if (!ast_strlen_zero(domain_context)) 08552 ast_string_field_set(p, context, domain_context); 08553 } 08554 08555 if (sip_debug_test_pvt(p)) 08556 ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain); 08557 08558 /* Check the dialplan for the username part of the request URI, 08559 the domain will be stored in the SIPDOMAIN variable 08560 Return 0 if we have a matching extension */ 08561 if (ast_exists_extension(NULL, p->context, uri, 1, from) || 08562 !strcmp(uri, ast_pickup_ext())) { 08563 if (!oreq) 08564 ast_string_field_set(p, exten, uri); 08565 return 0; 08566 } 08567 08568 /* Return 1 for pickup extension or overlap dialling support (if we support it) */ 08569 if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 08570 ast_canmatch_extension(NULL, p->context, uri, 1, from)) || 08571 !strncmp(uri, ast_pickup_ext(), strlen(uri))) { 08572 return 1; 08573 } 08574 08575 return -1; 08576 }
| static const char * get_header | ( | const struct sip_request * | req, | |
| const char * | name | |||
| ) | [static] |
Get header from SIP request.
Definition at line 4042 of file chan_sip.c.
References __get_header().
04043 { 04044 int start = 0; 04045 return __get_header(req, name, &start); 04046 }
| 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 2233 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().
02234 { 02235 const char *parse = tmp; 02236 char *first_bracket; 02237 02238 /* 02239 * Skip any quoted text until we find the part in brackets. 02240 * On any error give up and return the full string. 02241 */ 02242 while ( (first_bracket = strchr(parse, '<')) ) { 02243 char *first_quote = strchr(parse, '"'); 02244 02245 if (!first_quote || first_quote > first_bracket) 02246 break; /* no need to look at quoted part */ 02247 /* the bracket is within quotes, so ignore it */ 02248 parse = find_closing_quote(first_quote + 1, NULL); 02249 if (!*parse) { /* not found, return full string ? */ 02250 /* XXX or be robust and return in-bracket part ? */ 02251 ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp); 02252 break; 02253 } 02254 parse++; 02255 } 02256 if (first_bracket) { 02257 char *second_bracket = strchr(first_bracket + 1, '>'); 02258 if (second_bracket) { 02259 *second_bracket = '\0'; 02260 tmp = first_bracket + 1; 02261 } else { 02262 ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp); 02263 } 02264 } 02265 return tmp; 02266 }
| 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 9303 of file chan_sip.c.
References sip_request::line, and sip_request::lines.
Referenced by handle_request_notify(), and receive_message().
09304 { 09305 int x; 09306 int y; 09307 09308 buf[0] = '\0'; 09309 y = len - strlen(buf) - 5; 09310 if (y < 0) 09311 y = 0; 09312 for (x=0;x<req->lines;x++) { 09313 strncat(buf, req->line[x], y); /* safe */ 09314 y -= strlen(req->line[x]) + 1; 09315 if (y < 0) 09316 y = 0; 09317 if (y != 0) 09318 strcat(buf, "\n"); /* safe */ 09319 } 09320 return 0; 09321 }
| static int get_rdnis | ( | struct sip_pvt * | p, | |
| struct sip_request * | oreq | |||
| ) | [static] |
Get referring dnis.
Definition at line 8441 of file chan_sip.c.
References ast_log(), ast_string_field_set, ast_strlen_zero(), ast_verbose(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, sip_debug_test_pvt(), and strsep().
Referenced by handle_request_invite().
08442 { 08443 char tmp[256], *c, *a; 08444 struct sip_request *req; 08445 08446 req = oreq; 08447 if (!req) 08448 req = &p->initreq; 08449 ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); 08450 if (ast_strlen_zero(tmp)) 08451 return 0; 08452 c = get_in_brackets(tmp); 08453 if (strncmp(c, "sip:", 4)) { 08454 ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 08455 return -1; 08456 } 08457 c += 4; 08458 a = c; 08459 strsep(&a, "@;"); /* trim anything after @ or ; */ 08460 if (sip_debug_test_pvt(p)) 08461 ast_verbose("RDNIS is %s\n", c); 08462 ast_string_field_set(p, rdnis, c); 08463 08464 return 0; 08465 }
| 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 8635 of file chan_sip.c.
References ast_exists_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_verbose(), sip_refer::attendedtransfer, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_DEBUG, LOG_WARNING, ast_channel::macrocontext, option_debug, sip_pvt::owner, pbx_builtin_getvar_helper(), sip_pvt::refer, sip_refer::refer_to, sip_refer::refer_to_context, sip_refer::refer_to_domain, sip_refer::refer_to_urioption, sip_refer::referred_by, sip_refer::referred_by_name, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, S_OR, sip_debug_test_pvt(), and strcasestr().
Referenced by handle_request_refer().
08636 { 08637 08638 const char *p_referred_by = NULL; 08639 char *h_refer_to = NULL; 08640 char *h_referred_by = NULL; 08641 char *refer_to; 08642 const char *p_refer_to; 08643 char *referred_by_uri = NULL; 08644 char *ptr; 08645 struct sip_request *req = NULL; 08646 const char *transfer_context = NULL; 08647 struct sip_refer *referdata; 08648 08649 08650 req = outgoing_req; 08651 referdata = transferer->refer; 08652 08653 if (!req) 08654 req = &transferer->initreq; 08655 08656 p_refer_to = get_header(req, "Refer-To"); 08657 if (ast_strlen_zero(p_refer_to)) { 08658 ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n"); 08659 return -2; /* Syntax error */ 08660 } 08661 h_refer_to = ast_strdupa(p_refer_to); 08662 refer_to = get_in_brackets(h_refer_to); 08663 if (pedanticsipchecking) 08664 ast_uri_decode(refer_to); 08665 08666 if (strncasecmp(refer_to, "sip:", 4)) { 08667 ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 08668 return -3; 08669 } 08670 refer_to += 4; /* Skip sip: */ 08671 08672 /* Get referred by header if it exists */ 08673 p_referred_by = get_header(req, "Referred-By"); 08674 if (!ast_strlen_zero(p_referred_by)) { 08675 char *lessthan; 08676 h_referred_by = ast_strdupa(p_referred_by); 08677 if (pedanticsipchecking) 08678 ast_uri_decode(h_referred_by); 08679 08680 /* Store referrer's caller ID name */ 08681 ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name)); 08682 if ((lessthan = strchr(referdata->referred_by_name, '<'))) { 08683 *(lessthan - 1) = '\0'; /* Space */ 08684 } 08685 08686 referred_by_uri = get_in_brackets(h_referred_by); 08687 if(strncasecmp(referred_by_uri, "sip:", 4)) { 08688 ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 08689 referred_by_uri = (char *) NULL; 08690 } else { 08691 referred_by_uri += 4; /* Skip sip: */ 08692 } 08693 } 08694 08695 /* Check for arguments in the refer_to header */ 08696 if ((ptr = strchr(refer_to, '?'))) { /* Search for arguments */ 08697 *ptr++ = '\0'; 08698 if (!strncasecmp(ptr, "REPLACES=", 9)) { 08699 char *to = NULL, *from = NULL; 08700 08701 /* This is an attended transfer */ 08702 referdata->attendedtransfer = 1; 08703 ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid)); 08704 ast_uri_decode(referdata->replaces_callid); 08705 if ((ptr = strchr(referdata->replaces_callid, ';'))) /* Find options */ { 08706 *ptr++ = '\0'; 08707 } 08708 08709 if (ptr) { 08710 /* Find the different tags before we destroy the string */ 08711 to = strcasestr(ptr, "to-tag="); 08712 from = strcasestr(ptr, "from-tag="); 08713 } 08714 08715 /* Grab the to header */ 08716 if (to) { 08717 ptr = to + 7; 08718 if ((to = strchr(ptr, '&'))) 08719 *to = '\0'; 08720 if ((to = strchr(ptr, ';'))) 08721 *to = '\0'; 08722 ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag)); 08723 } 08724 08725 if (from) { 08726 ptr = from + 9; 08727 if ((to = strchr(ptr, '&'))) 08728 *to = '\0'; 08729 if ((to = strchr(ptr, ';'))) 08730 *to = '\0'; 08731 ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag)); 08732 } 08733 08734 if (option_debug > 1) { 08735 if (!pedanticsipchecking) 08736 ast_log(LOG_DEBUG,"Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid ); 08737 else 08738 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>" ); 08739 } 08740 } 08741 } 08742 08743 if ((ptr = strchr(refer_to, '@'))) { /* Separate domain */ 08744 char *urioption; 08745 08746 *ptr++ = '\0'; 08747 if ((urioption = strchr(ptr, ';'))) 08748 *urioption++ = '\0'; 08749 /* Save the domain for the dial plan */ 08750 ast_copy_string(referdata->refer_to_domain, ptr, sizeof(referdata->refer_to_domain)); 08751 if (urioption) 08752 ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption)); 08753 } 08754 08755 if ((ptr = strchr(refer_to, ';'))) /* Remove options */ 08756 *ptr = '\0'; 08757 ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to)); 08758 08759 if (referred_by_uri) { 08760 if ((ptr = strchr(referred_by_uri, ';'))) /* Remove options */ 08761 *ptr = '\0'; 08762 ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by)); 08763 } else { 08764 referdata->referred_by[0] = '\0'; 08765 } 08766 08767 /* Determine transfer context */ 08768 if (transferer->owner) /* Mimic behaviour in res_features.c */ 08769 transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); 08770 08771 /* By default, use the context in the channel sending the REFER */ 08772 if (ast_strlen_zero(transfer_context)) { 08773 transfer_context = S_OR(transferer->owner->macrocontext, 08774 S_OR(transferer->context, default_context)); 08775 } 08776 08777 ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context)); 08778 08779 /* Either an existing extension or the parking extension */ 08780 if (ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) { 08781 if (sip_debug_test_pvt(transferer)) { 08782 ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri); 08783 } 08784 /* We are ready to transfer to the extension */ 08785 return 0; 08786 } 08787 if (sip_debug_test_pvt(transferer)) 08788 ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context); 08789 08790 /* Failure, we can't find this extension */ 08791 return -1; 08792 }
| 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 8950 of file chan_sip.c.
References AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.
Referenced by check_user_full().
08951 { 08952 char *start; 08953 char *end; 08954 08955 start = strchr(input,':'); 08956 if (!start) { 08957 output[0] = '\0'; 08958 return 0; 08959 } 08960 start++; 08961 08962 /* we found "number" */ 08963 ast_copy_string(output,start,maxlen); 08964 output[maxlen-1] = '\0'; 08965 08966 end = strchr(output,'@'); 08967 if (end) 08968 *end = '\0'; 08969 else 08970 output[0] = '\0'; 08971 if (strstr(input,"privacy=full") || strstr(input,"privacy=uri")) 08972 return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; 08973 08974 return 0; 08975 }
| static const char * get_sdp | ( | struct sip_request * | req, | |
| const char * | name | |||
| ) | [static] |
Get a line from an SDP message body.
Definition at line 3945 of file chan_sip.c.
References get_sdp_iterate().
03946 { 03947 int dummy = 0; 03948 03949 return get_sdp_iterate(&dummy, req, name); 03950 }
| 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 3931 of file chan_sip.c.
References get_body_by_line(), len, and sip_request::line.
03932 { 03933 int len = strlen(name); 03934 03935 while (*start < req->sdp_end) { 03936 const char *r = get_body_by_line(req->line[(*start)++], name, len); 03937 if (r[0] != '\0') 03938 return r; 03939 } 03940 03941 return ""; 03942 }
| 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 8583 of file chan_sip.c.
References ast_channel_trylock, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::flags, iflist, sip_pvt::lock, LOG_DEBUG, match(), sip_pvt::next, option_debug, sip_pvt::owner, SIP_OUTGOING, and sip_pvt::tag.
Referenced by handle_request_invite(), and local_attended_transfer().
08584 { 08585 struct sip_pvt *sip_pvt_ptr; 08586 08587 ast_mutex_lock(&iflock); 08588 08589 if (option_debug > 3 && totag) 08590 ast_log(LOG_DEBUG, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>"); 08591 08592 /* Search interfaces and find the match */ 08593 for (sip_pvt_ptr = iflist; sip_pvt_ptr; sip_pvt_ptr = sip_pvt_ptr->next) { 08594 if (!strcmp(sip_pvt_ptr->callid, callid)) { 08595 int match = 1; 08596 char *ourtag = sip_pvt_ptr->tag; 08597 08598 /* Go ahead and lock it (and its owner) before returning */ 08599 ast_mutex_lock(&sip_pvt_ptr->lock); 08600 08601 /* Check if tags match. If not, this is not the call we want 08602 (With a forking SIP proxy, several call legs share the 08603 call id, but have different tags) 08604 */ 08605 if (pedanticsipchecking && (strcmp(fromtag, sip_pvt_ptr->theirtag) || strcmp(totag, ourtag))) 08606 match = 0; 08607 08608 if (!match) { 08609 ast_mutex_unlock(&sip_pvt_ptr->lock); 08610 continue; 08611 } 08612 08613 if (option_debug > 3 && totag) 08614 ast_log(LOG_DEBUG, "Matched %s call - their tag is %s Our tag is %s\n", 08615 ast_test_flag(&sip_pvt_ptr->flags[0], SIP_OUTGOING) ? "OUTGOING": "INCOMING", 08616 sip_pvt_ptr->theirtag, sip_pvt_ptr->tag); 08617 08618 /* deadlock avoidance... */ 08619 while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) { 08620 ast_mutex_unlock(&sip_pvt_ptr->lock); 08621 usleep(1); 08622 ast_mutex_lock(&sip_pvt_ptr->lock); 08623 } 08624 break; 08625 } 08626 } 08627 ast_mutex_unlock(&iflock); 08628 if (option_debug > 3 && !sip_pvt_ptr) 08629 ast_log(LOG_DEBUG, "Found no match for callid %s to-tag %s from-tag %s\n", callid, totag, fromtag); 08630 return sip_pvt_ptr; 08631 }
| static const char * gettag | ( | const struct sip_request * | req, | |
| const char * | header, | |||
| char * | tagbuf, | |||
| int | tagbufsize | |||
| ) | [static] |
Get tag from packet.
Definition at line 12847 of file chan_sip.c.
References get_header(), strcasestr(), and strsep().
Referenced by find_call(), handle_request(), and handle_response().
12848 { 12849 const char *thetag; 12850 12851 if (!tagbuf) 12852 return NULL; 12853 tagbuf[0] = '\0'; /* reset the buffer */ 12854 thetag = get_header(req, header); 12855 thetag = strcasestr(thetag, ";tag="); 12856 if (thetag) { 12857 thetag += 5; 12858 ast_copy_string(tagbuf, thetag, tagbufsize); 12859 return strsep(&tagbuf, ";"); 12860 } 12861 return NULL; 12862 }
| 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 15476 of file chan_sip.c.
References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), ast_variable::lineno, LOG_WARNING, ast_variable::name, SIP_CAN_REINVITE, SIP_CAN_REINVITE_NAT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_G726_NONSTANDARD, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, SIP_NAT_ROUTE, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_BUGGY_MWI, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NO, SIP_PROG_INBAND_YES, SIP_PROMISCREDIR, SIP_REINVITE, SIP_REINVITE_UPDATE, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USECLIENTCODE, strsep(), and ast_variable::value.
Referenced by build_peer(), build_user(), and reload_config().
15477 { 15478 int res = 1; 15479 static int dep_insecure_very = 0; 15480 static int dep_insecure_yes = 0; 15481 15482 if (!strcasecmp(v->name, "trustrpid")) { 15483 ast_set_flag(&mask[0], SIP_TRUSTRPID); 15484 ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID); 15485 } else if (!strcasecmp(v->name, "sendrpid")) { 15486 ast_set_flag(&mask[0], SIP_SENDRPID); 15487 ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID); 15488 } else if (!strcasecmp(v->name, "g726nonstandard")) { 15489 ast_set_flag(&mask[0], SIP_G726_NONSTANDARD); 15490 ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD); 15491 } else if (!strcasecmp(v->name, "useclientcode")) { 15492 ast_set_flag(&mask[0], SIP_USECLIENTCODE); 15493 ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE); 15494 } else if (!strcasecmp(v->name, "dtmfmode")) { 15495 ast_set_flag(&mask[0], SIP_DTMF); 15496 ast_clear_flag(&flags[0], SIP_DTMF); 15497 if (!strcasecmp(v->value, "inband")) 15498 ast_set_flag(&flags[0], SIP_DTMF_INBAND); 15499 else if (!strcasecmp(v->value, "rfc2833")) 15500 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 15501 else if (!strcasecmp(v->value, "info")) 15502 ast_set_flag(&flags[0], SIP_DTMF_INFO); 15503 else if (!strcasecmp(v->value, "auto")) 15504 ast_set_flag(&flags[0], SIP_DTMF_AUTO); 15505 else { 15506 ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno); 15507 ast_set_flag(&flags[0], SIP_DTMF_RFC2833); 15508 } 15509 } else if (!strcasecmp(v->name, "nat")) { 15510 ast_set_flag(&mask[0], SIP_NAT); 15511 ast_clear_flag(&flags[0], SIP_NAT); 15512 if (!strcasecmp(v->value, "never")) 15513 ast_set_flag(&flags[0], SIP_NAT_NEVER); 15514 else if (!strcasecmp(v->value, "route")) 15515 ast_set_flag(&flags[0], SIP_NAT_ROUTE); 15516 else if (ast_true(v->value)) 15517 ast_set_flag(&flags[0], SIP_NAT_ALWAYS); 15518 else 15519 ast_set_flag(&flags[0], SIP_NAT_RFC3581); 15520 } else if (!strcasecmp(v->name, "canreinvite")) { 15521 ast_set_flag(&mask[0], SIP_REINVITE); 15522 ast_clear_flag(&flags[0], SIP_REINVITE); 15523 if (ast_true(v->value)) { 15524 ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT); 15525 } else if (!ast_false(v->value)) { 15526 char buf[64]; 15527 char *word, *next = buf; 15528 15529 ast_copy_string(buf, v->value, sizeof(buf)); 15530 while ((word = strsep(&next, ","))) { 15531 if (!strcasecmp(word, "update")) { 15532 ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE); 15533 } else if (!strcasecmp(word, "nonat")) { 15534 ast_set_flag(&flags[0], SIP_CAN_REINVITE); 15535 ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT); 15536 } else { 15537 ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno); 15538 } 15539 } 15540 } 15541 } else if (!strcasecmp(v->name, "insecure")) { 15542 ast_set_flag(&mask[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 15543 ast_clear_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 15544 if (!strcasecmp(v->value, "very")) { 15545 ast_set_flag(&flags[0], SIP_INSECURE_PORT | SIP_INSECURE_INVITE); 15546 if (!dep_insecure_very) { 15547 ast_log(LOG_WARNING, "insecure=very at line %d is deprecated; use insecure=port,invite instead\n", v->lineno); 15548 dep_insecure_very = 1; 15549 } 15550 } 15551 else if (ast_true(v->value)) { 15552 ast_set_flag(&flags[0], SIP_INSECURE_PORT); 15553 if (!dep_insecure_yes) { 15554 ast_log(LOG_WARNING, "insecure=%s at line %d is deprecated; use insecure=port instead\n", v->value, v->lineno); 15555 dep_insecure_yes = 1; 15556 } 15557 } 15558 else if (!ast_false(v->value)) { 15559 char buf[64]; 15560 char *word, *next; 15561 15562 ast_copy_string(buf, v->value, sizeof(buf)); 15563 next = buf; 15564 while ((word = strsep(&next, ","))) { 15565 if (!strcasecmp(word, "port")) 15566 ast_set_flag(&flags[0], SIP_INSECURE_PORT); 15567 else if (!strcasecmp(word, "invite")) 15568 ast_set_flag(&flags[0], SIP_INSECURE_INVITE); 15569 else 15570 ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", v->value, v->lineno); 15571 } 15572 } 15573 } else if (!strcasecmp(v->name, "progressinband")) { 15574 ast_set_flag(&mask[0], SIP_PROG_INBAND); 15575 ast_clear_flag(&flags[0], SIP_PROG_INBAND); 15576 if (ast_true(v->value)) 15577 ast_set_flag(&flags[0], SIP_PROG_INBAND_YES); 15578 else if (strcasecmp(v->value, "never")) 15579 ast_set_flag(&flags[0], SIP_PROG_INBAND_NO); 15580 } else if (!strcasecmp(v->name, "promiscredir")) { 15581 ast_set_flag(&mask[0], SIP_PROMISCREDIR); 15582 ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR); 15583 } else if (!strcasecmp(v->name, "videosupport")) { 15584 ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT); 15585 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT); 15586 } else if (!strcasecmp(v->name, "allowoverlap")) { 15587 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP); 15588 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP); 15589 } else if (!strcasecmp(v->name, "allowsubscribe")) { 15590 ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE); 15591 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE); 15592 } else if (!strcasecmp(v->name, "t38pt_udptl")) { 15593 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_UDPTL); 15594 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_UDPTL); 15595 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 15596 } else if (!strcasecmp(v->name, "t38pt_rtp")) { 15597 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_RTP); 15598 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_RTP); 15599 } else if (!strcasecmp(v->name, "t38pt_tcp")) { 15600 ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT_TCP); 15601 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38SUPPORT_TCP); 15602 #endif 15603 } else if (!strcasecmp(v->name, "rfc2833compensate")) { 15604 ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE); 15605 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE); 15606 } else if (!strcasecmp(v->name, "buggymwi")) { 15607 ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI); 15608 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI); 15609 } else 15610 res = 0; 15611 15612 return res; 15613 }
| 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 13020 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_masquerade(), ast_channel_unlock, ast_frfree(), ast_hangup(), ast_log(), ast_mutex_unlock(), ast_quiet_chan(), ast_read(), ast_set_flag, ast_setstate(), ast_state2str(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, DEFAULT_TRANS_TIMEOUT, f, sip_pvt::flags, ast_channel::hangupcause, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, option_debug, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_call, SIP_DEFER_BYE_ON_TRANSFER, sip_scheddestroy(), ast_channel::tech_pvt, transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), and XMIT_RELIABLE.
Referenced by handle_request_invite().
13021 { 13022 struct ast_frame *f; 13023 int earlyreplace = 0; 13024 int oneleggedreplace = 0; /* Call with no bridge, propably IVR or voice message */ 13025 struct ast_channel *c = p->owner; /* Our incoming call */ 13026 struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */ 13027 struct ast_channel *targetcall; /* The bridge to the take-over target */ 13028 13029 /* Check if we're in ring state */ 13030 if (replacecall->_state == AST_STATE_RING) 13031 earlyreplace = 1; 13032 13033 /* Check if we have a bridge */ 13034 if (!(targetcall = ast_bridged_channel(replacecall))) { 13035 /* We have no bridge */ 13036 if (!earlyreplace) { 13037 if (option_debug > 1) 13038 ast_log(LOG_DEBUG, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name); 13039 oneleggedreplace = 1; 13040 } 13041 } 13042 if (option_debug > 3 && targetcall && targetcall->_state == AST_STATE_RINGING) 13043 ast_log(LOG_DEBUG, "SIP transfer: Target channel is in ringing state\n"); 13044 13045 if (option_debug > 3) { 13046 if (targetcall) 13047 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); 13048 else 13049 ast_log(LOG_DEBUG, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 13050 } 13051 13052 if (ignore) { 13053 ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n"); 13054 /* We should answer something here. If we are here, the 13055 call we are replacing exists, so an accepted 13056 can't harm */ 13057 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13058 /* Do something more clever here */ 13059 ast_channel_unlock(c); 13060 ast_mutex_unlock(&p->refer->refer_call->lock); 13061 return 1; 13062 } 13063 if (!c) { 13064 /* What to do if no channel ??? */ 13065 ast_log(LOG_ERROR, "Unable to create new channel. Invite/replace failed.\n"); 13066 transmit_response_reliable(p, "503 Service Unavailable", req); 13067 append_history(p, "Xfer", "INVITE/Replace Failed. No new channel."); 13068 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13069 ast_mutex_unlock(&p->refer->refer_call->lock); 13070 return 1; 13071 } 13072 append_history(p, "Xfer", "INVITE/Replace received"); 13073 /* We have three channels to play with 13074 channel c: New incoming call 13075 targetcall: Call from PBX to target 13076 p->refer->refer_call: SIP pvt dialog from transferer to pbx. 13077 replacecall: The owner of the previous 13078 We need to masq C into refer_call to connect to 13079 targetcall; 13080 If we are talking to internal audio stream, target call is null. 13081 */ 13082 13083 /* Fake call progress */ 13084 transmit_response(p, "100 Trying", req); 13085 ast_setstate(c, AST_STATE_RING); 13086 13087 /* Masquerade the new call into the referred call to connect to target call 13088 Targetcall is not touched by the masq */ 13089 13090 /* Answer the incoming call and set channel to UP state */ 13091 transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE); 13092 ast_setstate(c, AST_STATE_UP); 13093 13094 /* Stop music on hold and other generators */ 13095 ast_quiet_chan(replacecall); 13096 ast_quiet_chan(targetcall); 13097 if (option_debug > 3) 13098 ast_log(LOG_DEBUG, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name); 13099 /* Unlock clone, but not original (replacecall) */ 13100 ast_channel_unlock(c); 13101 13102 /* Unlock PVT */ 13103 ast_mutex_unlock(&p->refer->refer_call->lock); 13104 13105 /* Make sure that the masq does not free our PVT for the old call */ 13106 ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 13107 13108 /* Prepare the masquerade - if this does not happen, we will be gone */ 13109 if(ast_channel_masquerade(replacecall, c)) 13110 ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n"); 13111 else if (option_debug > 3) 13112 ast_log(LOG_DEBUG, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name); 13113 13114 /* The masquerade will happen as soon as someone reads a frame from the channel */ 13115 13116 /* C should now be in place of replacecall */ 13117 /* ast_read needs to lock channel */ 13118 ast_channel_unlock(c); 13119 13120 if (earlyreplace || oneleggedreplace ) { 13121 /* Force the masq to happen */ 13122 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13123 ast_frfree(f); 13124 f = NULL; 13125 if (option_debug > 3) 13126 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from RING channel!\n"); 13127 } else { 13128 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from RING channel \n"); 13129 } 13130 c->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 13131 ast_channel_unlock(replacecall); 13132 } else { /* Bridged call, UP channel */ 13133 if ((f = ast_read(replacecall))) { /* Force the masq to happen */ 13134 /* Masq ok */ 13135 ast_frfree(f); 13136 f = NULL; 13137 if (option_debug > 2) 13138 ast_log(LOG_DEBUG, "Invite/Replace: Could successfully read frame from channel! Masq done.\n"); 13139 } else { 13140 ast_log(LOG_WARNING, "Invite/Replace: Could not read frame from channel. Transfer failed\n"); 13141 } 13142 ast_channel_unlock(replacecall); 13143 } 13144 ast_mutex_unlock(&p->refer->refer_call->lock); 13145 13146 ast_setstate(c, AST_STATE_DOWN); 13147 if (option_debug > 3) { 13148 struct ast_channel *test; 13149 ast_log(LOG_DEBUG, "After transfer:----------------------------\n"); 13150 ast_log(LOG_DEBUG, " -- C: %s State %s\n", c->name, ast_state2str(c->_state)); 13151 if (replacecall) 13152 ast_log(LOG_DEBUG, " -- replacecall: %s State %s\n", replacecall->name, ast_state2str(replacecall->_state)); 13153 if (p->owner) { 13154 ast_log(LOG_DEBUG, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state)); 13155 test = ast_bridged_channel(p->owner); 13156 if (test) 13157 ast_log(LOG_DEBUG, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state)); 13158 else 13159 ast_log(LOG_DEBUG, " -- No call bridged to C->owner \n"); 13160 } else 13161 ast_log(LOG_DEBUG, " -- No channel yet \n"); 13162 ast_log(LOG_DEBUG, "End After transfer:----------------------------\n"); 13163 } 13164 13165 ast_channel_unlock(p->owner); /* Unlock new owner */ 13166 ast_mutex_unlock(&p->lock); /* Unlock SIP structure */ 13167 13168 /* The call should be down with no ast_channel, so hang it up */ 13169 c->tech_pvt = NULL; 13170 ast_hangup(c); 13171 return 0; 13172 }
| 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 14638 of file chan_sip.c.
References __sip_ack(), append_history, ast_inet_ntoa(), ast_log(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), check_pendings(), debug, DEFAULT_TRANS_TIMEOUT, error(), extract_uri(), FALSE, find_sdp(), FLAG_RESPONSE, sip_pvt::flags, get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), sip_request::header, sip_request::headers, cfsip_methods::id, sip_pvt::initreq, INV_TERMINATED, len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_request::method, option_debug, process_sdp(), sip_request::rlPart1, sip_request::rlPart2, SIP_ACK, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_debug_test_pvt(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_PKT_IGNORE_REQ, SIP_PKT_IGNORE_RESP, SIP_PKT_WITH_TOTAG, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_scheddestroy(), SIP_SUBSCRIBE, sip_pvt::tag, cfsip_methods::text, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and TRUE.
14639 { 14640 /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things 14641 relatively static */ 14642 const char *cmd; 14643 const char *cseq; 14644 const char *useragent; 14645 int seqno; 14646 int len; 14647 int ignore = FALSE; 14648 int respid; 14649 int res = 0; 14650 int debug = sip_debug_test_pvt(p); 14651 char *e; 14652 int error = 0; 14653 14654 /* Get Method and Cseq */ 14655 cseq = get_header(req, "Cseq"); 14656 cmd = req->header[0]; 14657 14658 /* Must have Cseq */ 14659 if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) { 14660 ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n"); 14661 error = 1; 14662 } 14663 if (!error && sscanf(cseq, "%d%n", &seqno, &len) != 1) { 14664 ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd); 14665 error = 1; 14666 } 14667 if (error) { 14668 if (!p->initreq.headers) /* New call */ 14669 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); /* Make sure we destroy this dialog */ 14670 return -1; 14671 } 14672 /* Get the command XXX */ 14673 14674 cmd = req->rlPart1; 14675 e = req->rlPart2; 14676 14677 /* Save useragent of the client */ 14678 useragent = get_header(req, "User-Agent"); 14679 if (!ast_strlen_zero(useragent)) 14680 ast_string_field_set(p, useragent, useragent); 14681 14682 /* Find out SIP method for incoming request */ 14683 if (req->method == SIP_RESPONSE) { /* Response to our request */ 14684 /* Response to our request -- Do some sanity checks */ 14685 if (!p->initreq.headers) { 14686 if (option_debug) 14687 ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd); 14688 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14689 return 0; 14690 } else if (p->ocseq && (p->ocseq < seqno)) { 14691 if (option_debug) 14692 ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq); 14693 return -1; 14694 } else if (p->ocseq && (p->ocseq != seqno)) { 14695 /* ignore means "don't do anything with it" but still have to 14696 respond appropriately */ 14697 ignore = TRUE; 14698 ast_set_flag(req, SIP_PKT_IGNORE); 14699 ast_set_flag(req, SIP_PKT_IGNORE_RESP); 14700 append_history(p, "Ignore", "Ignoring this retransmit\n"); 14701 } else if (e) { 14702 e = ast_skip_blanks(e); 14703 if (sscanf(e, "%d %n", &respid, &len) != 1) { 14704 ast_log(LOG_WARNING, "Invalid response: '%s'\n", e); 14705 } else { 14706 if (respid <= 0) { 14707 ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid); 14708 return 0; 14709 } 14710 /* More SIP ridiculousness, we have to ignore bogus contacts in 100 etc responses */ 14711 if ((respid == 200) || ((respid >= 300) && (respid <= 399))) 14712 extract_uri(p, req); 14713 handle_response(p, respid, e + len, req, ignore, seqno); 14714 } 14715 } 14716 return 0; 14717 } 14718 14719 /* New SIP request coming in 14720 (could be new request in existing SIP dialog as well...) 14721 */ 14722 14723 p->method = req->method; /* Find out which SIP method they are using */ 14724 if (option_debug > 3) 14725 ast_log(LOG_DEBUG, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 14726 14727 if (p->icseq && (p->icseq > seqno)) { 14728 if (option_debug) 14729 ast_log(LOG_DEBUG, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq); 14730 if (req->method != SIP_ACK) 14731 transmit_response(p, "503 Server error", req); /* We must respond according to RFC 3261 sec 12.2 */ 14732 return -1; 14733 } else if (p->icseq && 14734 p->icseq == seqno && 14735 req->method != SIP_ACK && 14736 (p->method != SIP_CANCEL || ast_test_flag(&p->flags[0], SIP_ALREADYGONE))) { 14737 /* ignore means "don't do anything with it" but still have to 14738 respond appropriately. We do this if we receive a repeat of 14739 the last sequence number */ 14740 ignore = 2; 14741 ast_set_flag(req, SIP_PKT_IGNORE); 14742 ast_set_flag(req, SIP_PKT_IGNORE_REQ); 14743 if (option_debug > 2) 14744 ast_log(LOG_DEBUG, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno); 14745 } 14746 14747 if (seqno >= p->icseq) 14748 /* Next should follow monotonically (but not necessarily 14749 incrementally -- thanks again to the genius authors of SIP -- 14750 increasing */ 14751 p->icseq = seqno; 14752 14753 /* Find their tag if we haven't got it */ 14754 if (ast_strlen_zero(p->theirtag)) { 14755 char tag[128]; 14756 14757 gettag(req, "From", tag, sizeof(tag)); 14758 ast_string_field_set(p, theirtag, tag); 14759 } 14760 snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd); 14761 14762 if (pedanticsipchecking) { 14763 /* If this is a request packet without a from tag, it's not 14764 correct according to RFC 3261 */ 14765 /* Check if this a new request in a new dialog with a totag already attached to it, 14766 RFC 3261 - section 12.2 - and we don't want to mess with recovery */ 14767 if (!p->initreq.headers && ast_test_flag(req, SIP_PKT_WITH_TOTAG)) { 14768 /* If this is a first request and it got a to-tag, it is not for us */ 14769 if (!ast_test_flag(req, SIP_PKT_IGNORE) && req->method == SIP_INVITE) { 14770 transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); 14771 /* Will cease to exist after ACK */ 14772 } else if (req->method != SIP_ACK) { 14773 transmit_response(p, "481 Call/Transaction Does Not Exist", req); 14774 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14775 } 14776 return res; 14777 } 14778 } 14779 14780 if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) { 14781 transmit_response(p, "400 Bad request", req); 14782 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14783 return -1; 14784 } 14785 14786 /* Handle various incoming SIP methods in requests */ 14787 switch (p->method) { 14788 case SIP_OPTIONS: 14789 res = handle_request_options(p, req); 14790 break; 14791 case SIP_INVITE: 14792 res = handle_request_invite(p, req, debug, seqno, sin, recount, e); 14793 break; 14794 case SIP_REFER: 14795 res = handle_request_refer(p, req, debug, ignore, seqno, nounlock); 14796 break; 14797 case SIP_CANCEL: 14798 res = handle_request_cancel(p, req); 14799 break; 14800 case SIP_BYE: 14801 res = handle_request_bye(p, req); 14802 break; 14803 case SIP_MESSAGE: 14804 res = handle_request_message(p, req); 14805 break; 14806 case SIP_SUBSCRIBE: 14807 res = handle_request_subscribe(p, req, sin, seqno, e); 14808 break; 14809 case SIP_REGISTER: 14810 res = handle_request_register(p, req, sin, e); 14811 break; 14812 case SIP_INFO: 14813 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14814 ast_verbose("Receiving INFO!\n"); 14815 if (!ignore) 14816 handle_request_info(p, req); 14817 else /* if ignoring, transmit response */ 14818 transmit_response(p, "200 OK", req); 14819 break; 14820 case SIP_NOTIFY: 14821 res = handle_request_notify(p, req, sin, seqno, e); 14822 break; 14823 case SIP_ACK: 14824 /* Make sure we don't ignore this */ 14825 if (seqno == p->pendinginvite) { 14826 p->invitestate = INV_TERMINATED; 14827 p->pendinginvite = 0; 14828 __sip_ack(p, seqno, FLAG_RESPONSE, 0); 14829 if (find_sdp(req)) { 14830 if (process_sdp(p, req)) 14831 return -1; 14832 } 14833 check_pendings(p); 14834 } 14835 /* Got an ACK that we did not match. Ignore silently */ 14836 if (!p->lastinvite && ast_strlen_zero(p->randdata)) 14837 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14838 break; 14839 default: 14840 transmit_response_with_allow(p, "501 Method Not Implemented", req, 0); 14841 ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 14842 cmd, ast_inet_ntoa(p->sa.sin_addr)); 14843 /* If this is some new method, and we don't have a call, destroy it now */ 14844 if (!p->initreq.headers) 14845 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14846 break; 14847 } 14848 return res; 14849 }
| static int handle_request_bye | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Handle incoming BYE request.
Definition at line 14217 of file chan_sip.c.
References append_history, ast_async_goto(), ast_bridged_channel(), AST_CONTROL_UNHOLD, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_rtp_get_quality(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, check_via(), context, copy_request(), DEFAULT_TRANS_TIMEOUT, sip_pvt::flags, get_also_info(), get_header(), sip_pvt::initreq, INV_TERMINATED, sip_pvt::invitestate, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_pvt::recv, sip_pvt::refer, sip_refer::refer_to, sip_pvt::rtp, sip_alreadygone(), SIP_NO_HISTORY, SIP_OUTGOING, SIP_PKT_IGNORE, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), and sip_pvt::vrtp.
Referenced by handle_request().
14218 { 14219 struct ast_channel *c=NULL; 14220 int res; 14221 struct ast_channel *bridged_to; 14222 14223 /* If we have an INCOMING invite that we haven't answered, terminate that transaction */ 14224 if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) 14225 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 14226 14227 p->invitestate = INV_TERMINATED; 14228 14229 copy_request(&p->initreq, req); 14230 check_via(p, req); 14231 sip_alreadygone(p); 14232 14233 /* Get RTCP quality before end of call */ 14234 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY) || p->owner) { 14235 char *audioqos, *videoqos; 14236 if (p->rtp) { 14237 audioqos = ast_rtp_get_quality(p->rtp, NULL); 14238 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 14239 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 14240 if (p->owner) 14241 pbx_builtin_setvar_helper(p->owner, "RTPAUDIOQOS", audioqos); 14242 } 14243 if (p->vrtp) { 14244 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 14245 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 14246 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 14247 if (p->owner) 14248 pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos); 14249 } 14250 } 14251 14252 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14253 14254 if (!ast_strlen_zero(get_header(req, "Also"))) { 14255 ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method. Ask vendor to support REFER instead\n", 14256 ast_inet_ntoa(p->recv.sin_addr)); 14257 if (ast_strlen_zero(p->context)) 14258 ast_string_field_set(p, context, default_context); 14259 res = get_also_info(p, req); 14260 if (!res) { 14261 c = p->owner; 14262 if (c) { 14263 bridged_to = ast_bridged_channel(c); 14264 if (bridged_to) { 14265 /* Don't actually hangup here... */ 14266 ast_queue_control(c, AST_CONTROL_UNHOLD); 14267 ast_async_goto(bridged_to, p->context, p->refer->refer_to,1); 14268 } else 14269 ast_queue_hangup(p->owner); 14270 } 14271 } else { 14272 ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr)); 14273 if (p->owner) 14274 ast_queue_hangup(p->owner); 14275 } 14276 } else if (p->owner) { 14277 ast_queue_hangup(p->owner); 14278 if (option_debug > 2) 14279 ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n"); 14280 } else { 14281 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14282 if (option_debug > 2) 14283 ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n"); 14284 } 14285 transmit_response(p, "200 OK", req); 14286 14287 return 1; 14288 }
| static int handle_request_cancel | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Handle incoming CANCEL request.
Definition at line 14129 of file chan_sip.c.
References ast_channel::_state, ast_log(), ast_queue_hangup(), AST_STATE_UP, check_via(), DEFAULT_TRANS_TIMEOUT, sip_pvt::initreq, INV_CANCELLED, sip_pvt::invitestate, sip_request::len, LOG_DEBUG, option_debug, sip_pvt::owner, sip_dual::req, sip_alreadygone(), sip_scheddestroy(), stop_media_flows(), transmit_response(), and transmit_response_reliable().
Referenced by handle_request().
14130 { 14131 14132 check_via(p, req); 14133 sip_alreadygone(p); 14134 p->invitestate = INV_CANCELLED; 14135 14136 if (p->owner && p->owner->_state == AST_STATE_UP) { 14137 /* This call is up, cancel is ignored, we need a bye */ 14138 transmit_response(p, "200 OK", req); 14139 if (option_debug) 14140 ast_log(LOG_DEBUG, "Got CANCEL on an answered call. Ignoring... \n"); 14141 return 0; 14142 } 14143 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 14144 14145 if (p->owner) 14146 ast_queue_hangup(p->owner); 14147 else 14148 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14149 if (p->initreq.len > 0) { 14150 transmit_response_reliable(p, "487 Request Terminated", &p->initreq); 14151 transmit_response(p, "200 OK", req); 14152 return 1; 14153 } else { 14154 transmit_response(p, "481 Call Leg Does Not Exist", req); 14155 return 0; 14156 } 14157 }
| static void handle_request_info | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Receive SIP INFO Message.
Definition at line 10775 of file chan_sip.c.
References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), ast_queue_control(), ast_queue_frame(), ast_strlen_zero(), ast_test_flag, ast_verbose(), ast_channel::cdr, DEFAULT_TRANS_TIMEOUT, event, f, sip_pvt::flags, get_body(), get_header(), LOG_WARNING, sip_pvt::owner, sip_scheddestroy(), SIP_USECLIENTCODE, sipdebug, and transmit_response().
Referenced by handle_request().
10776 { 10777 char buf[1024]; 10778 unsigned int event; 10779 const char *c = get_header(req, "Content-Type"); 10780 10781 /* Need to check the media/type */ 10782 if (!strcasecmp(c, "application/dtmf-relay") || 10783 !strcasecmp(c, "application/vnd.nortelnetworks.digits")) { 10784 unsigned int duration = 0; 10785 10786 /* Try getting the "signal=" part */ 10787 if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) { 10788 ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid); 10789 transmit_response(p, "200 OK", req); /* Should return error */ 10790 return; 10791 } else { 10792 ast_copy_string(buf, c, sizeof(buf)); 10793 } 10794 10795 if (!ast_strlen_zero((c = get_body(req, "Duration")))) 10796 duration = atoi(c); 10797 if (!duration) 10798 duration = 100; /* 100 ms */ 10799 10800 if (!p->owner) { /* not a PBX call */ 10801 transmit_response(p, "481 Call leg/transaction does not exist", req); 10802 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 10803 return; 10804 } 10805 10806 if (ast_strlen_zero(buf)) { 10807 transmit_response(p, "200 OK", req); 10808 return; 10809 } 10810 10811 if (buf[0] == '*') 10812 event = 10; 10813 else if (buf[0] == '#') 10814 event = 11; 10815 else if ((buf[0] >= 'A') && (buf[0] <= 'D')) 10816 event = 12 + buf[0] - 'A'; 10817 else 10818 event = atoi(buf); 10819 if (event == 16) { 10820 /* send a FLASH event */ 10821 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, }; 10822 ast_queue_frame(p->owner, &f); 10823 if (sipdebug) 10824 ast_verbose("* DTMF-relay event received: FLASH\n"); 10825 } else { 10826 /* send a DTMF event */ 10827 struct ast_frame f = { AST_FRAME_DTMF, }; 10828 if (event < 10) { 10829 f.subclass = '0' + event; 10830 } else if (event < 11) { 10831 f.subclass = '*'; 10832 } else if (event < 12) { 10833 f.subclass = '#'; 10834 } else if (event < 16) { 10835 f.subclass = 'A' + (event - 12); 10836 } 10837 f.len = duration; 10838 ast_queue_frame(p->owner, &f); 10839 if (sipdebug) 10840 ast_verbose("* DTMF-relay event received: %c\n", f.subclass); 10841 } 10842 transmit_response(p, "200 OK", req); 10843 return; 10844 } else if (!strcasecmp(c, "application/media_control+xml")) { 10845 /* Eh, we'll just assume it's a fast picture update for now */ 10846 if (p->owner) 10847 ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE); 10848 transmit_response(p, "200 OK", req); 10849 return; 10850 } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) { 10851 /* Client code (from SNOM phone) */ 10852 if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) { 10853 if (p->owner && p->owner->cdr) 10854 ast_cdr_setuserfield(p->owner, c); 10855 if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr) 10856 ast_cdr_setuserfield(ast_bridged_channel(p->owner), c); 10857 transmit_response(p, "200 OK", req); 10858 } else { 10859 transmit_response(p, "403 Unauthorized", req); 10860 } 10861 return; 10862 } 10863 /* Other type of INFO message, not really understood by Asterisk */ 10864 /* if (get_msg_text(buf, sizeof(buf), req)) { */ 10865 10866 ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf); 10867 transmit_response(p, "415 Unsupported media type", req); 10868 return; 10869 }
| static int handle_request_invite | ( | struct sip_pvt * | p, | |
| struct sip_request * | req, | |||
| int | debug, | |||
| int | seqno, | |||
| struct sockaddr_in * | sin, | |||
| int * | recount, | |||
| char * | e | |||
| ) | [static] |
Handle incoming INVITE request.
XXX: we should also check here does the other side supports t38 at all !!! XXX
Definition at line 13181 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_pickup_call(), ast_pickup_ext(), ast_queue_frame(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose(), AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), build_route(), sip_pvt::capability, check_user(), check_via(), context, copy_request(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, error(), exten, extract_uri(), FALSE, find_sdp(), sip_pvt::flags, get_destination(), get_header(), get_rdnis(), get_sip_pvt_byid_locked(), handle_invite_replaces(), ast_channel::hangupcause, sip_request::headers, INC_CALL_LIMIT, sip_pvt::initreq, INV_COMPLETED, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::jointcapability, sip_pvt::lastinvite, sip_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), option_debug, sip_pvt::owner, parse_ok_contact(), parse_sip_options(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, sip_pvt::rtp, S_OR, sip_alreadygone(), sip_cancel_destroy(), SIP_DTMF, SIP_DTMF_RFC2833, sip_handle_t38_reinvite(), SIP_INVITE, sip_new(), SIP_NO_HISTORY, SIP_OPT_REPLACES, SIP_OUTGOING, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PKT_IGNORE, sip_refer_allocate(), sip_scheddestroy(), sip_tech, sip_tech_info, sipdebug, sip_pvt::sipoptions, t38properties::state, strcasestr(), strsep(), sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_PEER_REINVITE, sip_pvt::tag, ast_channel::tech, ast_channel::tech_pvt, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, sip_pvt::udptl, update_call_counter(), XMIT_CRITICAL, and XMIT_RELIABLE.
Referenced by handle_request().
13182 { 13183 int res = 1; 13184 int gotdest; 13185 const char *p_replaces; 13186 char *replace_id = NULL; 13187 const char *required; 13188 unsigned int required_profile = 0; 13189 struct ast_channel *c = NULL; /* New channel */ 13190 13191 /* Find out what they support */ 13192 if (!p->sipoptions) { 13193 const char *supported = get_header(req, "Supported"); 13194 if (!ast_strlen_zero(supported)) 13195 parse_sip_options(p, supported); 13196 } 13197 13198 /* Find out what they require */ 13199 required = get_header(req, "Require"); 13200 if (!ast_strlen_zero(required)) { 13201 required_profile = parse_sip_options(NULL, required); 13202 if (required_profile && required_profile != SIP_OPT_REPLACES) { 13203 /* At this point we only support REPLACES */ 13204 transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required); 13205 ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required); 13206 p->invitestate = INV_COMPLETED; 13207 if (!p->lastinvite) 13208 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13209 return -1; 13210 } 13211 } 13212 13213 /* Check if this is a loop */ 13214 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { 13215 /* This is a call to ourself. Send ourselves an error code and stop 13216 processing immediately, as SIP really has no good mechanism for 13217 being able to call yourself */ 13218 /* If pedantic is on, we need to check the tags. If they're different, this is 13219 in fact a forked call through a SIP proxy somewhere. */ 13220 transmit_response(p, "482 Loop Detected", req); 13221 p->invitestate = INV_COMPLETED; 13222 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13223 return 0; 13224 } 13225 13226 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) { 13227 /* We already have a pending invite. Sorry. You are on hold. */ 13228 transmit_response(p, "491 Request Pending", req); 13229 if (option_debug) 13230 ast_log(LOG_DEBUG, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid); 13231 /* Don't destroy dialog here */ 13232 return 0; 13233 } 13234 13235 p_replaces = get_header(req, "Replaces"); 13236 if (!ast_strlen_zero(p_replaces)) { 13237 /* We have a replaces header */ 13238 char *ptr; 13239 char *fromtag = NULL; 13240 char *totag = NULL; 13241 char *start, *to; 13242 int error = 0; 13243 13244 if (p->owner) { 13245 if (option_debug > 2) 13246 ast_log(LOG_DEBUG, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid); 13247 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 13248 /* Do not destroy existing call */ 13249 return -1; 13250 } 13251 13252 if (sipdebug && option_debug > 2) 13253 ast_log(LOG_DEBUG, "INVITE part of call transfer. Replaces [%s]\n", p_replaces); 13254 /* Create a buffer we can manipulate */ 13255 replace_id = ast_strdupa(p_replaces); 13256 ast_uri_decode(replace_id); 13257 13258 if (!p->refer && !sip_refer_allocate(p)) { 13259 transmit_response(p, "500 Server Internal Error", req); 13260 append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory."); 13261 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13262 p->invitestate = INV_COMPLETED; 13263 return -1; 13264 } 13265 13266 /* Todo: (When we find phones that support this) 13267 if the replaces header contains ";early-only" 13268 we can only replace the call in early 13269 stage, not after it's up. 13270 13271 If it's not in early mode, 486 Busy. 13272 */ 13273 13274 /* Skip leading whitespace */ 13275 replace_id = ast_skip_blanks(replace_id); 13276 13277 start = replace_id; 13278 while ( (ptr = strsep(&start, ";")) ) { 13279 ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */ 13280 if ( (to = strcasestr(ptr, "to-tag=") ) ) 13281 totag = to + 7; /* skip the keyword */ 13282 else if ( (to = strcasestr(ptr, "from-tag=") ) ) { 13283 fromtag = to + 9; /* skip the keyword */ 13284 fromtag = strsep(&fromtag, "&"); /* trim what ? */ 13285 } 13286 } 13287 13288 if (sipdebug && option_debug > 3) 13289 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>"); 13290 13291 13292 /* Try to find call that we are replacing 13293 If we have a Replaces header, we need to cancel that call if we succeed with this call 13294 */ 13295 if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) { 13296 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id); 13297 transmit_response(p, "481 Call Leg Does Not Exist (Replaces)", req); 13298 error = 1; 13299 } 13300 13301 /* At this point, bot the pvt and the owner of the call to be replaced is locked */ 13302 13303 /* The matched call is the call from the transferer to Asterisk . 13304 We want to bridge the bridged part of the call to the 13305 incoming invite, thus taking over the refered call */ 13306 13307 if (p->refer->refer_call == p) { 13308 ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid); 13309 p->refer->refer_call = NULL; 13310 transmit_response(p, "400 Bad request", req); /* The best way to not not accept the transfer */ 13311 error = 1; 13312 } 13313 13314 if (!error && !p->refer->refer_call->owner) { 13315 /* Oops, someting wrong anyway, no owner, no call */ 13316 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id); 13317 /* Check for better return code */ 13318 transmit_response(p, "481 Call Leg Does Not Exist (Replace)", req); 13319 error = 1; 13320 } 13321 13322 if (!error && p->refer->refer_call->owner->_state != AST_STATE_RING && p->refer->refer_call->owner->_state != AST_STATE_UP ) { 13323 ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id); 13324 transmit_response(p, "603 Declined (Replaces)", req); 13325 error = 1; 13326 } 13327 13328 if (error) { /* Give up this dialog */ 13329 append_history(p, "Xfer", "INVITE/Replace Failed."); 13330 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13331 ast_mutex_unlock(&p->lock); 13332 if (p->refer->refer_call) { 13333 ast_mutex_unlock(&p->refer->refer_call->lock); 13334 ast_channel_unlock(p->refer->refer_call->owner); 13335 } 13336 p->invitestate = INV_COMPLETED; 13337 return -1; 13338 } 13339 } 13340 13341 13342 /* Check if this is an INVITE that sets up a new dialog or 13343 a re-invite in an existing dialog */ 13344 13345 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 13346 int newcall = (p->initreq.headers ? TRUE : FALSE); 13347 13348 sip_cancel_destroy(p); 13349 /* This also counts as a pending invite */ 13350 p->pendinginvite = seqno; 13351 check_via(p, req); 13352 13353 copy_request(&p->initreq, req); /* Save this INVITE as the transaction basis */ 13354 if (!p->owner) { /* Not a re-invite */ 13355 if (debug) 13356 ast_verbose("Using INVITE request as basis request - %s\n", p->callid); 13357 if (newcall) 13358 append_history(p, "Invite", "New call: %s", p->callid); 13359 parse_ok_contact(p, req); 13360 } else { /* Re-invite on existing call */ 13361 ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ 13362 /* Handle SDP here if we already have an owner */ 13363 if (find_sdp(req)) { 13364 if (process_sdp(p, req)) { 13365 transmit_response(p, "488 Not acceptable here", req); 13366 if (!p->lastinvite) 13367 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13368 return -1; 13369 } 13370 } else { 13371 p->jointcapability = p->capability; 13372 if (option_debug) 13373 ast_log(LOG_DEBUG, "Hm.... No sdp for the moment\n"); 13374 } 13375 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a response, note what it was for */ 13376 append_history(p, "ReInv", "Re-invite received"); 13377 } 13378 } else if (debug) 13379 ast_verbose("Ignoring this INVITE request\n"); 13380 13381 13382 if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) { 13383 /* This is a new invite */ 13384 /* Handle authentication if this is our first invite */ 13385 res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin); 13386 if (res == AUTH_CHALLENGE_SENT) { 13387 p->invitestate = INV_COMPLETED; /* Needs to restart in another INVITE transaction */ 13388 return 0; 13389 } 13390 if (res < 0) { /* Something failed in authentication */ 13391 if (res == AUTH_FAKE_AUTH) { 13392 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 13393 transmit_fake_auth_response(p, req, 1); 13394 } else { 13395 ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From")); 13396 transmit_response_reliable(p, "403 Forbidden", req); 13397 } 13398 p->invitestate = INV_COMPLETED; 13399 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13400 ast_string_field_free(p, theirtag); 13401 return 0; 13402 } 13403 13404 /* We have a succesful authentication, process the SDP portion if there is one */ 13405 if (find_sdp(req)) { 13406 if (process_sdp(p, req)) { 13407 /* Unacceptable codecs */ 13408 transmit_response_reliable(p, "488 Not acceptable here", req); 13409 p->invitestate = INV_COMPLETED; 13410 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13411 if (option_debug) 13412 ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n"); 13413 return -1; 13414 } 13415 } else { /* No SDP in invite, call control session */ 13416 p->jointcapability = p->capability; 13417 if (option_debug > 1) 13418 ast_log(LOG_DEBUG, "No SDP in Invite, third party call control\n"); 13419 } 13420 13421 /* Queue NULL frame to prod ast_rtp_bridge if appropriate */ 13422 /* This seems redundant ... see !p-owner above */ 13423 if (p->owner) 13424 ast_queue_frame(p->owner, &ast_null_frame); 13425 13426 13427 /* Initialize the context if it hasn't been already */ 13428 if (ast_strlen_zero(p->context)) 13429 ast_string_field_set(p, context, default_context); 13430 13431 13432 /* Check number of concurrent calls -vs- incoming limit HERE */ 13433 if (option_debug) 13434 ast_log(LOG_DEBUG, "Checking SIP call limits for device %s\n", p->username); 13435 if ((res = update_call_counter(p, INC_CALL_LIMIT))) { 13436 if (res < 0) { 13437 ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username); 13438 transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req); 13439 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13440 p->invitestate = INV_COMPLETED; 13441 } 13442 return 0; 13443 } 13444 gotdest = get_destination(p, NULL); /* Get destination right away */ 13445 get_rdnis(p, NULL); /* Get redirect information */ 13446 extract_uri(p, req); /* Get the Contact URI */ 13447 build_contact(p); /* Build our contact header */ 13448 13449 if (p->rtp) { 13450 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 13451 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 13452 } 13453 13454 if (!replace_id && gotdest) { /* No matching extension found */ 13455 if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 13456 transmit_response_reliable(p, "484 Address Incomplete", req); 13457 else 13458 transmit_response_reliable(p, "404 Not Found", req); 13459 p->invitestate = INV_COMPLETED; 13460 update_call_counter(p, DEC_CALL_LIMIT); 13461 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13462 return 0; 13463 } else { 13464 /* If no extension was specified, use the s one */ 13465 /* Basically for calling to IP/Host name only */ 13466 if (ast_strlen_zero(p->exten)) 13467 ast_string_field_set(p, exten, "s"); 13468 /* Initialize our tag */ 13469 13470 make_our_tag(p->tag, sizeof(p->tag)); 13471 /* First invitation - create the channel */ 13472 c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL)); 13473 *recount = 1; 13474 13475 /* Save Record-Route for any later requests we make on this dialogue */ 13476 build_route(p, req, 0); 13477 13478 if (c) { 13479 /* Pre-lock the call */ 13480 ast_channel_lock(c); 13481 } 13482 } 13483 } else { 13484 if (option_debug > 1 && sipdebug) { 13485 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 13486 ast_log(LOG_DEBUG, "Got a SIP re-invite for call %s\n", p->callid); 13487 else 13488 ast_log(LOG_DEBUG, "Got a SIP re-transmit of INVITE for call %s\n", p->callid); 13489 } 13490 c = p->owner; 13491 } 13492 13493 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 13494 p->lastinvite = seqno; 13495 13496 if (replace_id) { /* Attended transfer or call pickup - we're the target */ 13497 /* Go and take over the target call */ 13498 if (sipdebug && option_debug > 3) 13499 ast_log(LOG_DEBUG, "Sending this call to the invite/replcaes handler %s\n", p->callid); 13500 return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin); 13501 } 13502 13503 13504 if (c) { /* We have a call -either a new call or an old one (RE-INVITE) */ 13505 switch(c->_state) { 13506 case AST_STATE_DOWN: 13507 if (option_debug > 1) 13508 ast_log(LOG_DEBUG, "%s: New call is still down.... Trying... \n", c->name); 13509 transmit_response(p, "100 Trying", req); 13510 p->invitestate = INV_PROCEEDING; 13511 ast_setstate(c, AST_STATE_RING); 13512 if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */ 13513 enum ast_pbx_result res; 13514 13515 res = ast_pbx_start(c); 13516 13517 switch(res) { 13518 case AST_PBX_FAILED: 13519 ast_log(LOG_WARNING, "Failed to start PBX :(\n"); 13520 p->invitestate = INV_COMPLETED; 13521 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13522 transmit_response(p, "503 Unavailable", req); 13523 else 13524 transmit_response_reliable(p, "503 Unavailable", req); 13525 break; 13526 case AST_PBX_CALL_LIMIT: 13527 ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n"); 13528 p->invitestate = INV_COMPLETED; 13529 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13530 transmit_response(p, "480 Temporarily Unavailable", req); 13531 else 13532 transmit_response_reliable(p, "480 Temporarily Unavailable", req); 13533 break; 13534 case AST_PBX_SUCCESS: 13535 /* nothing to do */ 13536 break; 13537 } 13538 13539 if (res) { 13540 13541 /* Unlock locks so ast_hangup can do its magic */ 13542 ast_mutex_unlock(&c->lock); 13543 ast_mutex_unlock(&p->lock); 13544 ast_hangup(c); 13545 ast_mutex_lock(&p->lock); 13546 c = NULL; 13547 } 13548 } else { /* Pickup call in call group */ 13549 ast_channel_unlock(c); 13550 if (ast_pickup_call(c)) { 13551 ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid); 13552 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13553 transmit_response(p, "503 Unavailable", req); /* OEJ - Right answer? */ 13554 else 13555 transmit_response_reliable(p, "503 Unavailable", req); 13556 sip_alreadygone(p); 13557 /* Unlock locks so ast_hangup can do its magic */ 13558 ast_mutex_unlock(&p->lock); 13559 c->hangupcause = AST_CAUSE_CALL_REJECTED; 13560 } else { 13561 ast_mutex_unlock(&p->lock); 13562 ast_setstate(c, AST_STATE_DOWN); 13563 c->hangupcause = AST_CAUSE_NORMAL_CLEARING; 13564 } 13565 p->invitestate = INV_COMPLETED; 13566 ast_hangup(c); 13567 ast_mutex_lock(&p->lock); 13568 c = NULL; 13569 } 13570 break; 13571 case AST_STATE_RING: 13572 transmit_response(p, "100 Trying", req); 13573 p->invitestate = INV_PROCEEDING; 13574 break; 13575 case AST_STATE_RINGING: 13576 transmit_response(p, "180 Ringing", req); 13577 p->invitestate = INV_PROCEEDING; 13578 break; 13579 case AST_STATE_UP: 13580 if (option_debug > 1) 13581 ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); 13582 13583 if (p->t38.state == T38_PEER_REINVITE) { 13584 struct ast_channel *bridgepeer = NULL; 13585 struct sip_pvt *bridgepvt = NULL; 13586 13587 if ((bridgepeer = ast_bridged_channel(p->owner))) { 13588 /* 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*/ 13589 /*! XXX: we should also check here does the other side supports t38 at all !!! XXX */ 13590 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 13591 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 13592 if (bridgepvt->t38.state == T38_DISABLED) { 13593 if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */ 13594 /* Send re-invite to the bridged channel */ 13595 sip_handle_t38_reinvite(bridgepeer, p, 1); 13596 } else { /* Something is wrong with peers udptl struct */ 13597 ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n"); 13598 ast_mutex_lock(&bridgepvt->lock); 13599 bridgepvt->t38.state = T38_DISABLED; 13600 ast_mutex_unlock(&bridgepvt->lock); 13601 if (option_debug > 1) 13602 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name); 13603 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13604 transmit_response(p, "488 Not acceptable here", req); 13605 else 13606 transmit_response_reliable(p, "488 Not acceptable here", req); 13607 13608 } 13609 } else { 13610 /* The other side is already setup for T.38 most likely so we need to acknowledge this too */ 13611 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 13612 p->t38.state = T38_ENABLED; 13613 if (option_debug) 13614 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13615 } 13616 } else { 13617 /* Other side is not a SIP channel */ 13618 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13619 transmit_response(p, "488 Not acceptable here", req); 13620 else 13621 transmit_response_reliable(p, "488 Not acceptable here", req); 13622 p->t38.state = T38_DISABLED; 13623 if (option_debug > 1) 13624 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13625 13626 if (!p->lastinvite) /* Only destroy if this is *not* a re-invite */ 13627 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13628 } 13629 } else { 13630 /* we are not bridged in a call */ 13631 transmit_response_with_t38_sdp(p, "200 OK", req, XMIT_CRITICAL); 13632 p->t38.state = T38_ENABLED; 13633 if (option_debug) 13634 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 13635 } 13636 } else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */ 13637 int sendok = TRUE; 13638 13639 /* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */ 13640 /* so handle it here (re-invite other party to RTP) */ 13641 struct ast_channel *bridgepeer = NULL; 13642 struct sip_pvt *bridgepvt = NULL; 13643 if ((bridgepeer = ast_bridged_channel(p->owner))) { 13644 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 13645 bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt; 13646 /* Does the bridged peer have T38 ? */ 13647 if (bridgepvt->t38.state == T38_ENABLED) { 13648 ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n"); 13649 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 13650 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13651 transmit_response(p, "488 Not Acceptable Here (unsupported)", req); 13652 else 13653 transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req); 13654 sendok = FALSE; 13655 } 13656 /* No bridged peer with T38 enabled*/ 13657 } 13658 } 13659 /* Respond to normal re-invite */ 13660 if (sendok) 13661 transmit_response_with_sdp(p, "200 OK", req, XMIT_CRITICAL); 13662 13663 } 13664 p->invitestate = INV_TERMINATED; 13665 break; 13666 default: 13667 ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state); 13668 transmit_response(p, "100 Trying", req); 13669 break; 13670 } 13671 } else { 13672 if (p && (p->autokillid == -1)) { 13673 const char *msg; 13674 13675 if (!p->jointcapability) 13676 msg = "488 Not Acceptable Here (codec error)"; 13677 else { 13678 ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n"); 13679 msg = "503 Unavailable"; 13680 } 13681 if (ast_test_flag(req, SIP_PKT_IGNORE)) 13682 transmit_response(p, msg, req); 13683 else 13684 transmit_response_reliable(p, msg, req); 13685 p->invitestate = INV_COMPLETED; 13686 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13687 } 13688 } 13689 return res; 13690 }
| static int handle_request_message | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Handle incoming MESSAGE request.
Definition at line 14291 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().
14292 { 14293 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 14294 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14295 ast_verbose("Receiving message!\n"); 14296 receive_message(p, req); 14297 } else 14298 transmit_response(p, "202 Accepted", req); 14299 return 1; 14300 }
| 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 12865 of file chan_sip.c.
References ast_log(), DEFAULT_TRANS_TIMEOUT, event, FALSE, get_header(), get_msg_text(), sip_pvt::lastinvite, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, sip_scheddestroy(), sipdebug, transmit_response(), and TRUE.
Referenced by handle_request().
12866 { 12867 /* This is mostly a skeleton for future improvements */ 12868 /* Mostly created to return proper answers on notifications on outbound REFER's */ 12869 int res = 0; 12870 const char *event = get_header(req, "Event"); 12871 char *eventid = NULL; 12872 char *sep; 12873 12874 if( (sep = strchr(event, ';')) ) { /* XXX bug here - overwriting string ? */ 12875 *sep++ = '\0'; 12876 eventid = sep; 12877 } 12878 12879 if (option_debug > 1 && sipdebug) 12880 ast_log(LOG_DEBUG, "Got NOTIFY Event: %s\n", event); 12881 12882 if (strcmp(event, "refer")) { 12883 /* We don't understand this event. */ 12884 /* Here's room to implement incoming voicemail notifications :-) */ 12885 transmit_response(p, "489 Bad event", req); 12886 res = -1; 12887 } else { 12888 /* Save nesting depth for now, since there might be other events we will 12889 support in the future */ 12890 12891 /* Handle REFER notifications */ 12892 12893 char buf[1024]; 12894 char *cmd, *code; 12895 int respcode; 12896 int success = TRUE; 12897 12898 /* EventID for each transfer... EventID is basically the REFER cseq 12899 12900 We are getting notifications on a call that we transfered 12901 We should hangup when we are getting a 200 OK in a sipfrag 12902 Check if we have an owner of this event */ 12903 12904 /* Check the content type */ 12905 if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) { 12906 /* We need a sipfrag */ 12907 transmit_response(p, "400 Bad request", req); 12908 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12909 return -1; 12910 } 12911 12912 /* Get the text of the attachment */ 12913 if (get_msg_text(buf, sizeof(buf), req)) { 12914 ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); 12915 transmit_response(p, "400 Bad request", req); 12916 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12917 return -1; 12918 } 12919 12920 /* 12921 From the RFC... 12922 A minimal, but complete, implementation can respond with a single 12923 NOTIFY containing either the body: 12924 SIP/2.0 100 Trying 12925 12926 if the subscription is pending, the body: 12927 SIP/2.0 200 OK 12928 if the reference was successful, the body: 12929 SIP/2.0 503 Service Unavailable 12930 if the reference failed, or the body: 12931 SIP/2.0 603 Declined 12932 12933 if the REFER request was accepted before approval to follow the 12934 reference could be obtained and that approval was subsequently denied 12935 (see Section 2.4.7). 12936 12937 If there are several REFERs in the same dialog, we need to 12938 match the ID of the event header... 12939 */ 12940 if (option_debug > 2) 12941 ast_log(LOG_DEBUG, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf); 12942 cmd = ast_skip_blanks(buf); 12943 code = cmd; 12944 /* We are at SIP/2.0 */ 12945 while(*code && (*code > 32)) { /* Search white space */ 12946 code++; 12947 } 12948 *code++ = '\0'; 12949 code = ast_skip_blanks(code); 12950 sep = code; 12951 sep++; 12952 while(*sep && (*sep > 32)) { /* Search white space */ 12953 sep++; 12954 } 12955 *sep++ = '\0'; /* Response string */ 12956 respcode = atoi(code); 12957 switch (respcode) { 12958 case 100: /* Trying: */ 12959 case 101: /* dialog establishment */ 12960 /* Don't do anything yet */ 12961 break; 12962 case 183: /* Ringing: */ 12963 /* Don't do anything yet */ 12964 break; 12965 case 200: /* OK: The new call is up, hangup this call */ 12966 /* Hangup the call that we are replacing */ 12967 break; 12968 case 301: /* Moved permenantly */ 12969 case 302: /* Moved temporarily */ 12970 /* Do we get the header in the packet in this case? */ 12971 success = FALSE; 12972 break; 12973 case 503: /* Service Unavailable: The new call failed */ 12974 /* Cancel transfer, continue the call */ 12975 success = FALSE; 12976 break; 12977 case 603: /* Declined: Not accepted */ 12978 /* Cancel transfer, continue the current call */ 12979 success = FALSE; 12980 break; 12981 } 12982 if (!success) { 12983 ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n"); 12984 } 12985 12986 /* Confirm that we received this packet */ 12987 transmit_response(p, "200 OK", req); 12988 }; 12989 12990 if (!p->lastinvite) 12991 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12992 12993 return res; 12994 }
| static int handle_request_options | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Handle incoming OPTIONS request.
Definition at line 12997 of file chan_sip.c.
References ast_string_field_set, ast_strlen_zero(), build_contact(), context, DEFAULT_TRANS_TIMEOUT, get_destination(), sip_pvt::lastinvite, sip_scheddestroy(), and transmit_response_with_allow().
Referenced by handle_request().
12998 { 12999 int res; 13000 13001 res = get_destination(p, req); 13002 build_contact(p); 13003 /* XXX Should we authenticate OPTIONS? XXX */ 13004 if (ast_strlen_zero(p->context)) 13005 ast_string_field_set(p, context, default_context); 13006 if (res < 0) 13007 transmit_response_with_allow(p, "404 Not Found", req, 0); 13008 else 13009 transmit_response_with_allow(p, "200 OK", req, 0); 13010 /* Destroy if this OPTIONS was the opening request, but not if 13011 it's in the middle of a normal call flow. */ 13012 if (!p->lastinvite) 13013 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 13014 13015 return res; 13016 }
| 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 13856 of file chan_sip.c.
References sip_pvt::allowtransfer, append_history, ast_async_goto(), ast_bridged_channel(), AST_CAUSE_NORMAL_CLEARING, ast_channel_unlock, ast_clear_flag, AST_CONTROL_UNHOLD, AST_LIST_EMPTY, ast_log(), ast_parking_ext(), ast_queue_control(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), sip_refer::attendedtransfer, sip_dual::chan1, sip_dual::chan2, check_sip_domain(), context, copy_request(), FALSE, sip_pvt::flags, get_refer_info(), ast_channel::hangupcause, local_attended_transfer(), sip_refer::localtransfer, LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, REFER_200OK, REFER_FAILED, REFER_SENT, sip_refer::refer_to, sip_refer::refer_to_context, sip_refer::refer_to_domain, sip_refer::referred_by, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, sip_dual::req, sip_alreadygone(), SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_NEEDDESTROY, SIP_OUTGOING, sip_park(), SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_refer_allocate(), sipdebug, sip_refer::status, TRANSFER_CLOSED, transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by handle_request().
13857 { 13858 struct sip_dual current; /* Chan1: Call between asterisk and transferer */ 13859 /* Chan2: Call between asterisk and transferee */ 13860 13861 int res = 0; 13862 13863 if (ast_test_flag(req, SIP_PKT_DEBUG)) 13864 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"); 13865 13866 if (!p->owner) { 13867 /* This is a REFER outside of an existing SIP dialog */ 13868 /* We can't handle that, so decline it */ 13869 if (option_debug > 2) 13870 ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid); 13871 transmit_response(p, "603 Declined (No dialog)", req); 13872 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 13873 append_history(p, "Xfer", "Refer failed. Outside of dialog."); 13874 sip_alreadygone(p); 13875 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 13876 } 13877 return 0; 13878 } 13879 13880 13881 /* Check if transfer is allowed from this device */ 13882 if (p->allowtransfer == TRANSFER_CLOSED ) { 13883 /* Transfer not allowed, decline */ 13884 transmit_response(p, "603 Declined (policy)", req); 13885 append_history(p, "Xfer", "Refer failed. Allowtransfer == closed."); 13886 /* Do not destroy SIP session */ 13887 return 0; 13888 } 13889 13890 if(!ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 13891 /* Already have a pending REFER */ 13892 transmit_response(p, "491 Request pending", req); 13893 append_history(p, "Xfer", "Refer failed. Request pending."); 13894 return 0; 13895 } 13896 13897 /* Allocate memory for call transfer data */ 13898 if (!p->refer && !sip_refer_allocate(p)) { 13899 transmit_response(p, "500 Internal Server Error", req); 13900 append_history(p, "Xfer", "Refer failed. Memory allocation error."); 13901 return -3; 13902 } 13903 13904 res = get_refer_info(p, req); /* Extract headers */ 13905 13906 p->refer->status = REFER_SENT; 13907 13908 if (res != 0) { 13909 switch (res) { 13910 case -2: /* Syntax error */ 13911 transmit_response(p, "400 Bad Request (Refer-to missing)", req); 13912 append_history(p, "Xfer", "Refer failed. Refer-to missing."); 13913 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 13914 ast_log(LOG_DEBUG, "SIP transfer to black hole can't be handled (no refer-to: )\n"); 13915 break; 13916 case -3: 13917 transmit_response(p, "603 Declined (Non sip: uri)", req); 13918 append_history(p, "Xfer", "Refer failed. Non SIP uri"); 13919 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 13920 ast_log(LOG_DEBUG, "SIP transfer to non-SIP uri denied\n"); 13921 break; 13922 default: 13923 /* Refer-to extension not found, fake a failed transfer */ 13924 transmit_response(p, "202 Accepted", req); 13925 append_history(p, "Xfer", "Refer failed. Bad extension."); 13926 transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE); 13927 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 13928 if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug) 13929 ast_log(LOG_DEBUG, "SIP transfer to bad extension: %s\n", p->refer->refer_to); 13930 break; 13931 } 13932 return 0; 13933 } 13934 if (ast_strlen_zero(p->context)) 13935 ast_string_field_set(p, context, default_context); 13936 13937 /* If we do not support SIP domains, all transfers are local */ 13938 if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) { 13939 p->refer->localtransfer = 1; 13940 if (sipdebug && option_debug > 2) 13941 ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain); 13942 } else if (AST_LIST_EMPTY(&domain_list)) { 13943 /* This PBX don't bother with SIP domains, so all transfers are local */ 13944 p->refer->localtransfer = 1; 13945 } else 13946 if (sipdebug && option_debug > 2) 13947 ast_log(LOG_DEBUG, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain); 13948 13949 /* Is this a repeat of a current request? Ignore it */ 13950 /* Don't know what else to do right now. */ 13951 if (ignore) 13952 return res; 13953 13954 /* If this is a blind transfer, we have the following 13955 channels to work with: 13956 - chan1, chan2: The current call between transferer and transferee (2 channels) 13957 - target_channel: A new call from the transferee to the target (1 channel) 13958 We need to stay tuned to what happens in order to be able 13959 to bring back the call to the transferer */ 13960 13961 /* If this is a attended transfer, we should have all call legs within reach: 13962 - chan1, chan2: The call between the transferer and transferee (2 channels) 13963 - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels) 13964 We want to bridge chan2 with targetcall_pvt! 13965 13966 The replaces call id in the refer message points 13967 to the call leg between Asterisk and the transferer. 13968 So we need to connect the target and the transferee channel 13969 and hangup the two other channels silently 13970 13971 If the target is non-local, the call ID could be on a remote 13972 machine and we need to send an INVITE with replaces to the 13973 target. We basically handle this as a blind transfer 13974 and let the sip_call function catch that we need replaces 13975 header in the INVITE. 13976 */ 13977 13978 13979 /* Get the transferer's channel */ 13980 current.chan1 = p->owner; 13981 13982 /* Find the other part of the bridge (2) - transferee */ 13983 current.chan2 = ast_bridged_channel(current.chan1); 13984 13985 if (sipdebug && option_debug > 2) 13986 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>"); 13987 13988 if (!current.chan2 && !p->refer->attendedtransfer) { 13989 /* No bridged channel, propably IVR or echo or similar... */ 13990 /* Guess we should masquerade or something here */ 13991 /* Until we figure it out, refuse transfer of such calls */ 13992 if (sipdebug && option_debug > 2) 13993 ast_log(LOG_DEBUG,"Refused SIP transfer on non-bridged channel.\n"); 13994 p->refer->status = REFER_FAILED; 13995 append_history(p, "Xfer", "Refer failed. Non-bridged channel."); 13996 transmit_response(p, "603 Declined", req); 13997 return -1; 13998 } 13999 14000 if (current.chan2) { 14001 if (sipdebug && option_debug > 3) 14002 ast_log(LOG_DEBUG, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name); 14003 14004 ast_queue_control(current.chan1, AST_CONTROL_UNHOLD); 14005 } 14006 14007 ast_set_flag(&p->flags[0], SIP_GOTREFER); 14008 14009 /* Attended transfer: Find all call legs and bridge transferee with target*/ 14010 if (p->refer->attendedtransfer) { 14011 if ((res = local_attended_transfer(p, ¤t, req, seqno))) 14012 return res; /* We're done with the transfer */ 14013 /* Fall through for remote transfers that we did not find locally */ 14014 if (sipdebug && option_debug > 3) 14015 ast_log(LOG_DEBUG, "SIP attended transfer: Still not our call - generating INVITE with replaces\n"); 14016 /* Fallthrough if we can't find the call leg internally */ 14017 } 14018 14019 14020 /* Parking a call */ 14021 if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) { 14022 /* Must release c's lock now, because it will not longer be accessible after the transfer! */ 14023 *nounlock = 1; 14024 ast_channel_unlock(current.chan1); 14025 copy_request(¤t.req, req); 14026 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14027 p->refer->status = REFER_200OK; 14028 append_history(p, "Xfer", "REFER to call parking."); 14029 if (sipdebug && option_debug > 3) 14030 ast_log(LOG_DEBUG, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name); 14031 sip_park(current.chan2, current.chan1, req, seqno); 14032 return res; 14033 } 14034 14035 /* Blind transfers and remote attended xfers */ 14036 transmit_response(p, "202 Accepted", req); 14037 14038 if (current.chan1 && current.chan2) { 14039 if (option_debug > 2) 14040 ast_log(LOG_DEBUG, "chan1->name: %s\n", current.chan1->name); 14041 pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name); 14042 } 14043 if (current.chan2) { 14044 pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name); 14045 pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain); 14046 pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes"); 14047 /* One for the new channel */ 14048 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes"); 14049 /* Attended transfer to remote host, prepare headers for the INVITE */ 14050 if (p->refer->referred_by) 14051 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by); 14052 } 14053 /* Generate a Replaces string to be used in the INVITE during attended transfer */ 14054 if (p->refer->replaces_callid && !ast_strlen_zero(p->refer->replaces_callid)) { 14055 char tempheader[BUFSIZ]; 14056 snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 14057 p->refer->replaces_callid_totag ? ";to-tag=" : "", 14058 p->refer->replaces_callid_totag, 14059 p->refer->replaces_callid_fromtag ? ";from-tag=" : "", 14060 p->refer->replaces_callid_fromtag); 14061 if (current.chan2) 14062 pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader); 14063 } 14064 /* Must release lock now, because it will not longer 14065 be accessible after the transfer! */ 14066 *nounlock = 1; 14067 ast_channel_unlock(current.chan1); 14068 ast_channel_unlock(current.chan2); 14069 14070 /* Connect the call */ 14071 14072 /* FAKE ringing if not attended transfer */ 14073 if (!p->refer->attendedtransfer) 14074 transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 14075 14076 /* For blind transfer, this will lead to a new call */ 14077 /* For attended transfer to remote host, this will lead to 14078 a new SIP call with a replaces header, if the dial plan allows it 14079 */ 14080 if (!current.chan2) { 14081 /* We have no bridge, so we're talking with Asterisk somehow */ 14082 /* We need to masquerade this call */ 14083 /* What to do to fix this situation: 14084 * Set up the new call in a new channel 14085 * Let the new channel masq into this channel 14086 Please add that code here :-) 14087 */ 14088 p->refer->status = REFER_FAILED; 14089 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE); 14090 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14091 append_history(p, "Xfer", "Refer failed (only bridged calls)."); 14092 return -1; 14093 } 14094 ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 14095 14096 /* For blind transfers, move the call to the new extensions. For attended transfers on multiple 14097 servers - generate an INVITE with Replaces. Either way, let the dial plan decided */ 14098 res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1); 14099 14100 if (!res) { 14101 /* Success - we have a new channel */ 14102 if (option_debug > 2) 14103 ast_log(LOG_DEBUG, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 14104 transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE); 14105 if (p->refer->localtransfer) 14106 p->refer->status = REFER_200OK; 14107 if (p->owner) 14108 p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; 14109 append_history(p, "Xfer", "Refer succeeded."); 14110 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14111 /* Do not hangup call, the other side do that when we say 200 OK */ 14112 /* We could possibly implement a timer here, auto congestion */ 14113 res = 0; 14114 } else { 14115 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */ 14116 if (option_debug > 2) 14117 ast_log(LOG_DEBUG, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind"); 14118 append_history(p, "Xfer", "Refer failed."); 14119 /* Failure of some kind */ 14120 p->refer->status = REFER_FAILED; 14121 transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE); 14122 ast_clear_flag(&p->flags[0], SIP_GOTREFER); 14123 res = -1; 14124 } 14125 return res; 14126 }
| 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 14594 of file chan_sip.c.
References append_history, ast_inet_ntoa(), ast_log(), ast_test_flag, ast_verbose(), AUTH_NOT_FOUND, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, check_via(), copy_request(), DEFAULT_TRANS_TIMEOUT, get_header(), sip_pvt::initreq, LOG_NOTICE, register_verify(), SIP_PKT_DEBUG, and sip_scheddestroy().
Referenced by handle_request().
14595 { 14596 enum check_auth_result res; 14597 14598 /* Use this as the basis */ 14599 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14600 ast_verbose("Using latest REGISTER request as basis request\n"); 14601 copy_request(&p->initreq, req); 14602 check_via(p, req); 14603 if ((res = register_verify(p, sin, req, e)) < 0) { 14604 const char *reason = ""; 14605 14606 switch (res) { 14607 case AUTH_SECRET_FAILED: 14608 reason = "Wrong password"; 14609 break; 14610 case AUTH_USERNAME_MISMATCH: 14611 reason = "Username/auth name mismatch"; 14612 break; 14613 case AUTH_NOT_FOUND: 14614 reason = "No matching peer found"; 14615 break; 14616 case AUTH_UNKNOWN_DOMAIN: 14617 reason = "Not a local domain"; 14618 break; 14619 default: 14620 break; 14621 } 14622 ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n", 14623 get_header(req, "To"), ast_inet_ntoa(sin->sin_addr), 14624 reason); 14625 } 14626 if (res < 1) { 14627 /* Destroy the session, but keep us around for just a bit in case they don't 14628 get our 200 OK */ 14629 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14630 } 14631 append_history(p, "RegRequest", "%s : Account %s", res ? "Failed": "Succeeded", get_header(req, "To")); 14632 return res; 14633 }
| 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 14303 of file chan_sip.c.
References append_history, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_UNLOCK, ASTOBJ_UNREF, ASTOBJ_WRLOCK, AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), cb_extensionstate(), check_user_full(), check_via(), context, copy_request(), CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, event, sip_pvt::expiry, FALSE, sip_pvt::flags, get_destination(), get_header(), sip_request::headers, iflist, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::laststate, sip_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, sip_peer::mailbox, make_our_tag(), sip_request::method, sip_peer::mwipvt, sip_pvt::next, NONE, option_debug, parse_ok_contact(), PIDF_XML, sip_pvt::relatedpeer, sip_pvt::sa, sip_cancel_destroy(), sip_destroy(), sip_destroy_peer(), sip_methods, SIP_NEEDDESTROY, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PKT_DEBUG, SIP_PKT_IGNORE, sip_scheddestroy(), sip_send_mwi_to_peer(), SIP_SUBSCRIBE, sipdebug, sip_pvt::stateid, sip_pvt::subscribed, sip_pvt::tag, cfsip_methods::text, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_state_notify(), and XPIDF_XML.
Referenced by handle_request().
14304 { 14305 int gotdest; 14306 int res = 0; 14307 int firststate = AST_EXTENSION_REMOVED; 14308 struct sip_peer *authpeer = NULL; 14309 const char *eventheader = get_header(req, "Event"); /* Get Event package name */ 14310 const char *accept = get_header(req, "Accept"); 14311 int resubscribe = (p->subscribed != NONE); 14312 char *temp, *event; 14313 14314 if (p->initreq.headers) { 14315 /* We already have a dialog */ 14316 if (p->initreq.method != SIP_SUBSCRIBE) { 14317 /* This is a SUBSCRIBE within another SIP dialog, which we do not support */ 14318 /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */ 14319 transmit_response(p, "403 Forbidden (within dialog)", req); 14320 /* Do not destroy session, since we will break the call if we do */ 14321 if (option_debug) 14322 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); 14323 return 0; 14324 } else if (ast_test_flag(req, SIP_PKT_DEBUG)) { 14325 if (option_debug) { 14326 if (resubscribe) 14327 ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid); 14328 else 14329 ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid); 14330 } 14331 } 14332 } 14333 14334 /* Check if we have a global disallow setting on subscriptions. 14335 if so, we don't have to check peer/user settings after auth, which saves a lot of processing 14336 */ 14337 if (!global_allowsubscribe) { 14338 transmit_response(p, "403 Forbidden (policy)", req); 14339 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14340 return 0; 14341 } 14342 14343 if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) { /* Set up dialog, new subscription */ 14344 /* Use this as the basis */ 14345 if (ast_test_flag(req, SIP_PKT_DEBUG)) 14346 ast_verbose("Creating new subscription\n"); 14347 14348 copy_request(&p->initreq, req); 14349 check_via(p, req); 14350 } else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE)) 14351 ast_verbose("Ignoring this SUBSCRIBE request\n"); 14352 14353 /* Find parameters to Event: header value and remove them for now */ 14354 if (ast_strlen_zero(eventheader)) { 14355 transmit_response(p, "489 Bad Event", req); 14356 if (option_debug > 1) 14357 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: <none>\n"); 14358 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14359 return 0; 14360 } 14361 14362 if ( (strchr(eventheader, ';'))) { 14363 event = ast_strdupa(eventheader); /* Since eventheader is a const, we can't change it */ 14364 temp = strchr(event, ';'); 14365 *temp = '\0'; /* Remove any options for now */ 14366 /* We might need to use them later :-) */ 14367 } else 14368 event = (char *) eventheader; /* XXX is this legal ? */ 14369 14370 /* Handle authentication */ 14371 res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer); 14372 /* if an authentication response was sent, we are done here */ 14373 if (res == AUTH_CHALLENGE_SENT) { 14374 if (authpeer) 14375 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14376 return 0; 14377 } 14378 if (res < 0) { 14379 if (res == AUTH_FAKE_AUTH) { 14380 ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From")); 14381 transmit_fake_auth_response(p, req, 1); 14382 } else { 14383 ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From")); 14384 transmit_response_reliable(p, "403 Forbidden", req); 14385 } 14386 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14387 if (authpeer) 14388 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14389 return 0; 14390 } 14391 14392 /* Check if this user/peer is allowed to subscribe at all */ 14393 if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) { 14394 transmit_response(p, "403 Forbidden (policy)", req); 14395 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14396 if (authpeer) 14397 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14398 return 0; 14399 } 14400 14401 /* Get destination right away */ 14402 gotdest = get_destination(p, NULL); 14403 14404 /* Initialize the context if it hasn't been already; 14405 note this is done _after_ handling any domain lookups, 14406 because the context specified there is for calls, not 14407 subscriptions 14408 */ 14409 if (!ast_strlen_zero(p->subscribecontext)) 14410 ast_string_field_set(p, context, p->subscribecontext); 14411 else if (ast_strlen_zero(p->context)) 14412 ast_string_field_set(p, context, default_context); 14413 14414 /* Get full contact header - this needs to be used as a request URI in NOTIFY's */ 14415 parse_ok_contact(p, req); 14416 14417 build_contact(p); 14418 if (gotdest) { 14419 transmit_response(p, "404 Not Found", req); 14420 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14421 if (authpeer) 14422 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14423 return 0; 14424 } 14425 14426 /* Initialize tag for new subscriptions */ 14427 if (ast_strlen_zero(p->tag)) 14428 make_our_tag(p->tag, sizeof(p->tag)); 14429 14430 if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */ 14431 if (authpeer) /* No need for authpeer here */ 14432 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14433 14434 /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */ 14435 /* Polycom phones only handle xpidf+xml, even if they say they can 14436 handle pidf+xml as well 14437 */ 14438 if (strstr(p->useragent, "Polycom")) { 14439 p->subscribed = XPIDF_XML; 14440 } else if (strstr(accept, "application/pidf+xml")) { 14441 p->subscribed = PIDF_XML; /* RFC 3863 format */ 14442 } else if (strstr(accept, "application/dialog-info+xml")) { 14443 p->subscribed = DIALOG_INFO_XML; 14444 /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */ 14445 } else if (strstr(accept, "application/cpim-pidf+xml")) { 14446 p->subscribed = CPIM_PIDF_XML; /* RFC 3863 format */ 14447 } else if (strstr(accept, "application/xpidf+xml")) { 14448 p->subscribed = XPIDF_XML; /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */ 14449 } else if (ast_strlen_zero(accept)) { 14450 if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */ 14451 transmit_response(p, "489 Bad Event", req); 14452 14453 ast_log(LOG_WARNING,"SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 14454 p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 14455 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14456 return 0; 14457 } 14458 /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least. 14459 so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */ 14460 } else { 14461 /* Can't find a format for events that we know about */ 14462 char mybuf[200]; 14463 snprintf(mybuf,sizeof(mybuf),"489 Bad Event (format %s)", accept); 14464 transmit_response(p, mybuf, req); 14465 14466 ast_log(LOG_WARNING,"SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n", 14467 accept, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri); 14468 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14469 return 0; 14470 } 14471 } else if (!strcmp(event, "message-summary")) { 14472 if (!ast_strlen_zero(accept) && strcmp(accept, "application/simple-message-summary")) { 14473 /* Format requested that we do not support */ 14474 transmit_response(p, "406 Not Acceptable", req); 14475 if (option_debug > 1) 14476 ast_log(LOG_DEBUG, "Received SIP mailbox subscription for unknown format: %s\n", accept); 14477 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14478 if (authpeer) /* No need for authpeer here */ 14479 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14480 return 0; 14481 } 14482 /* Looks like they actually want a mailbox status 14483 This version of Asterisk supports mailbox subscriptions 14484 The subscribed URI needs to exist in the dial plan 14485 In most devices, this is configurable to the voicemailmain extension you use 14486 */ 14487 if (!authpeer || ast_strlen_zero(authpeer->mailbox)) { 14488 transmit_response(p, "404 Not found (no mailbox)", req); 14489 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14490 ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name); 14491 if (authpeer) /* No need for authpeer here */ 14492 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14493 return 0; 14494 } 14495 14496 p->subscribed = MWI_NOTIFICATION; 14497 if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */ 14498 /* We only allow one subscription per peer */ 14499 sip_destroy(authpeer->mwipvt); 14500 authpeer->mwipvt = p; /* Link from peer to pvt */ 14501 p->relatedpeer = authpeer; /* Link from pvt to peer */ 14502 } else { /* At this point, Asterisk does not understand the specified event */ 14503 transmit_response(p, "489 Bad Event", req); 14504 if (option_debug > 1) 14505 ast_log(LOG_DEBUG, "Received SIP subscribe for unknown event package: %s\n", event); 14506 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14507 if (authpeer) /* No need for authpeer here */ 14508 ASTOBJ_UNREF(authpeer, sip_destroy_peer); 14509 return 0; 14510 } 14511 14512 if (p->subscribed != MWI_NOTIFICATION && !resubscribe) 14513 p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p); 14514 14515 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p) 14516 p->lastinvite = seqno; 14517 if (p && !ast_test_flag(&p->flags[0], SIP_NEEDDESTROY)) { 14518 p->expiry = atoi(get_header(req, "Expires")); 14519 14520 /* check if the requested expiry-time is within the approved limits from sip.conf */ 14521 if (p->expiry > max_expiry) 14522 p->expiry = max_expiry; 14523 if (p->expiry < min_expiry && p->expiry > 0) 14524 p->expiry = min_expiry; 14525 14526 if (sipdebug || option_debug > 1) { 14527 if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer) 14528 ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox); 14529 else 14530 ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username); 14531 } 14532 if (p->autokillid > -1) 14533 sip_cancel_destroy(p); /* Remove subscription expiry for renewals */ 14534 if (p->expiry > 0) 14535 sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */ 14536 14537 if (p->subscribed == MWI_NOTIFICATION) { 14538 transmit_response(p, "200 OK", req); 14539 if (p->relatedpeer) { /* Send first notification */ 14540 ASTOBJ_WRLOCK(p->relatedpeer); 14541 sip_send_mwi_to_peer(p->relatedpeer); 14542 ASTOBJ_UNLOCK(p->relatedpeer); 14543 } 14544 } else { 14545 struct sip_pvt *p_old; 14546 14547 if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { 14548 14549 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)); 14550 transmit_response(p, "404 Not found", req); 14551 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14552 return 0; 14553 } 14554 14555 transmit_response(p, "200 OK", req); 14556 transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */ 14557 append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate)); 14558 /* hide the 'complete' exten/context in the refer_to field for later display */ 14559 ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context); 14560 14561 /* remove any old subscription from this peer for the same exten/context, 14562 as the peer has obviously forgotten about it and it's wasteful to wait 14563 for it to expire and send NOTIFY messages to the peer only to have them 14564 ignored (or generate errors) 14565 */ 14566 ast_mutex_lock(&iflock); 14567 for (p_old = iflist; p_old; p_old = p_old->next) { 14568 if (p_old == p) 14569 continue; 14570 if (p_old->initreq.method != SIP_SUBSCRIBE) 14571 continue; 14572 if (p_old->subscribed == NONE) 14573 continue; 14574 ast_mutex_lock(&p_old->lock); 14575 if (!strcmp(p_old->username, p->username)) { 14576 if (!strcmp(p_old->exten, p->exten) && 14577 !strcmp(p_old->context, p->context)) { 14578 ast_set_flag(&p_old->flags[0], SIP_NEEDDESTROY); 14579 ast_mutex_unlock(&p_old->lock); 14580 break; 14581 } 14582 } 14583 ast_mutex_unlock(&p_old->lock); 14584 } 14585 ast_mutex_unlock(&iflock); 14586 } 14587 if (!p->expiry) 14588 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 14589 } 14590 return 1; 14591 }
| 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 12205 of file chan_sip.c.
References __sip_ack(), __sip_semi_ack(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_set_flag, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), do_proxy_auth(), FALSE, find_sdp(), find_sip_method(), sip_pvt::flags, get_header(), gettag(), handle_response_invite(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), hangup_sip2cause(), ast_channel::hangupcause, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, sip_pvt::method, NONE, option_debug, option_verbose, sip_pvt::owner, parse_moved_contact(), process_sdp(), sip_pvt::refer, sip_pvt::relatedpeer, SIP_ACK, sip_alreadygone(), SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NEEDDESTROY, SIP_NOTIFY, SIP_OPTIONS, SIP_OUTGOING, SIP_PKT_DEBUG, SIP_PKT_IGNORE, SIP_REFER, SIP_REGISTER, sipdebug, stop_media_flows(), sip_pvt::subscribed, text, transmit_request(), VERBOSE_PREFIX_3, and XMIT_UNRELIABLE.
12206 { 12207 struct ast_channel *owner; 12208 int sipmethod; 12209 int res = 1; 12210 const char *c = get_header(req, "Cseq"); 12211 const char *msg = strchr(c, ' '); 12212 12213 if (!msg) 12214 msg = ""; 12215 else 12216 msg++; 12217 sipmethod = find_sip_method(msg); 12218 12219 owner = p->owner; 12220 if (owner) 12221 owner->hangupcause = hangup_sip2cause(resp); 12222 12223 /* Acknowledge whatever it is destined for */ 12224 if ((resp >= 100) && (resp <= 199)) 12225 __sip_semi_ack(p, seqno, 0, sipmethod); 12226 else 12227 __sip_ack(p, seqno, 0, sipmethod); 12228 12229 /* Get their tag if we haven't already */ 12230 if (ast_strlen_zero(p->theirtag) || (resp >= 200)) { 12231 char tag[128]; 12232 12233 gettag(req, "To", tag, sizeof(tag)); 12234 ast_string_field_set(p, theirtag, tag); 12235 } 12236 if (p->relatedpeer && p->method == SIP_OPTIONS) { 12237 /* We don't really care what the response is, just that it replied back. 12238 Well, as long as it's not a 100 response... since we might 12239 need to hang around for something more "definitive" */ 12240 if (resp != 100) 12241 handle_response_peerpoke(p, resp, req); 12242 } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 12243 switch(resp) { 12244 case 100: /* 100 Trying */ 12245 case 101: /* 101 Dialog establishment */ 12246 if (sipmethod == SIP_INVITE) 12247 handle_response_invite(p, resp, rest, req, seqno); 12248 break; 12249 case 183: /* 183 Session Progress */ 12250 if (sipmethod == SIP_INVITE) 12251 handle_response_invite(p, resp, rest, req, seqno); 12252 break; 12253 case 180: /* 180 Ringing */ 12254 if (sipmethod == SIP_INVITE) 12255 handle_response_invite(p, resp, rest, req, seqno); 12256 break; 12257 case 200: /* 200 OK */ 12258 p->authtries = 0; /* Reset authentication counter */ 12259 if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) { 12260 /* We successfully transmitted a message 12261 or a video update request in INFO */ 12262 /* Nothing happens here - the message is inside a dialog */ 12263 } else if (sipmethod == SIP_INVITE) { 12264 handle_response_invite(p, resp, rest, req, seqno); 12265 } else if (sipmethod == SIP_NOTIFY) { 12266 /* They got the notify, this is the end */ 12267 if (p->owner) { 12268 if (!p->refer) { 12269 ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name); 12270 ast_queue_hangup(p->owner); 12271 } else if (option_debug > 3) 12272 ast_log(LOG_DEBUG, "Got OK on REFER Notify message\n"); 12273 } else { 12274 if (p->subscribed == NONE) 12275 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12276 } 12277 } else if (sipmethod == SIP_REGISTER) 12278 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12279 else if (sipmethod == SIP_BYE) /* Ok, we're ready to go */ 12280 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12281 break; 12282 case 202: /* Transfer accepted */ 12283 if (sipmethod == SIP_REFER) 12284 handle_response_refer(p, resp, rest, req, seqno); 12285 break; 12286 case 401: /* Not www-authorized on SIP method */ 12287 if (sipmethod == SIP_INVITE) 12288 handle_response_invite(p, resp, rest, req, seqno); 12289 else if (sipmethod == SIP_REFER) 12290 handle_response_refer(p, resp, rest, req, seqno); 12291 else if (p->registry && sipmethod == SIP_REGISTER) 12292 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12293 else { 12294 ast_log(LOG_WARNING, "Got authentication request (401) on unknown %s to '%s'\n", sip_methods[sipmethod].text, get_header(req, "To")); 12295 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12296 } 12297 break; 12298 case 403: /* Forbidden - we failed authentication */ 12299 if (sipmethod == SIP_INVITE) 12300 handle_response_invite(p, resp, rest, req, seqno); 12301 else if (p->registry && sipmethod == SIP_REGISTER) 12302 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12303 else { 12304 ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg); 12305 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12306 } 12307 break; 12308 case 404: /* Not found */ 12309 if (p->registry && sipmethod == SIP_REGISTER) 12310 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12311 else if (sipmethod == SIP_INVITE) 12312 handle_response_invite(p, resp, rest, req, seqno); 12313 else if (owner) 12314 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12315 break; 12316 case 407: /* Proxy auth required */ 12317 if (sipmethod == SIP_INVITE) 12318 handle_response_invite(p, resp, rest, req, seqno); 12319 else if (sipmethod == SIP_REFER) 12320 handle_response_refer(p, resp, rest, req, seqno); 12321 else if (p->registry && sipmethod == SIP_REGISTER) 12322 res = handle_response_register(p, resp, rest, req, ignore, seqno); 12323 else if (sipmethod == SIP_BYE) { 12324 if (ast_strlen_zero(p->authname)) 12325 ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n", 12326 msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 12327 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12328 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization", sipmethod, 0)) { 12329 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12330 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12331 } 12332 } else /* We can't handle this, giving up in a bad way */ 12333 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12334 12335 break; 12336 case 481: /* Call leg does not exist */ 12337 if (sipmethod == SIP_INVITE) { 12338 handle_response_invite(p, resp, rest, req, seqno); 12339 } else if (sipmethod == SIP_REFER) { 12340 handle_response_refer(p, resp, rest, req, seqno); 12341 } else if (sipmethod == SIP_BYE) { 12342 /* The other side has no transaction to bye, 12343 just assume it's all right then */ 12344 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12345 } else if (sipmethod == SIP_CANCEL) { 12346 /* The other side has no transaction to cancel, 12347 just assume it's all right then */ 12348 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12349 } else { 12350 ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid); 12351 /* Guessing that this is not an important request */ 12352 } 12353 break; 12354 case 487: 12355 if (sipmethod == SIP_INVITE) 12356 handle_response_invite(p, resp, rest, req, seqno); 12357 break; 12358 case 488: /* Not acceptable here - codec error */ 12359 if (sipmethod == SIP_INVITE) 12360 handle_response_invite(p, resp, rest, req, seqno); 12361 break; 12362 case 491: /* Pending */ 12363 if (sipmethod == SIP_INVITE) 12364 handle_response_invite(p, resp, rest, req, seqno); 12365 else { 12366 if (option_debug) 12367 ast_log(LOG_DEBUG, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid); 12368 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12369 } 12370 break; 12371 case 501: /* Not Implemented */ 12372 if (sipmethod == SIP_INVITE) 12373 handle_response_invite(p, resp, rest, req, seqno); 12374 else if (sipmethod == SIP_REFER) 12375 handle_response_refer(p, resp, rest, req, seqno); 12376 else 12377 ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg); 12378 break; 12379 case 603: /* Declined transfer */ 12380 if (sipmethod == SIP_REFER) { 12381 handle_response_refer(p, resp, rest, req, seqno); 12382 break; 12383 } 12384 /* Fallthrough */ 12385 default: 12386 if ((resp >= 300) && (resp < 700)) { 12387 /* Fatal response */ 12388 if ((option_verbose > 2) && (resp != 487)) 12389 ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr)); 12390 12391 if (sipmethod == SIP_INVITE) 12392 stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12393 12394 /* XXX Locking issues?? XXX */ 12395 switch(resp) { 12396 case 300: /* Multiple Choices */ 12397 case 301: /* Moved permenantly */ 12398 case 302: /* Moved temporarily */ 12399 case 305: /* Use Proxy */ 12400 parse_moved_contact(p, req); 12401 /* Fall through */ 12402 case 486: /* Busy here */ 12403 case 600: /* Busy everywhere */ 12404 case 603: /* Decline */ 12405 if (p->owner) 12406 ast_queue_control(p->owner, AST_CONTROL_BUSY); 12407 break; 12408 case 482: /* 12409 \note SIP is incapable of performing a hairpin call, which 12410 is yet another failure of not having a layer 2 (again, YAY 12411 IETF for thinking ahead). So we treat this as a call 12412 forward and hope we end up at the right place... */ 12413 if (option_debug) 12414 ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n"); 12415 if (p->owner) 12416 ast_string_field_build(p->owner, call_forward, 12417 "Local/%s@%s", p->username, p->context); 12418 /* Fall through */ 12419 case 480: /* Temporarily Unavailable */ 12420 case 404: /* Not Found */ 12421 case 410: /* Gone */ 12422 case 400: /* Bad Request */ 12423 case 500: /* Server error */ 12424 if (sipmethod == SIP_REFER) { 12425 handle_response_refer(p, resp, rest, req, seqno); 12426 break; 12427 } 12428 /* Fall through */ 12429 case 503: /* Service Unavailable */ 12430 case 504: /* Server Timeout */ 12431 if (owner) 12432 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12433 break; 12434 default: 12435 /* Send hangup */ 12436 if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 12437 ast_queue_hangup(p->owner); 12438 break; 12439 } 12440 /* ACK on invite */ 12441 if (sipmethod == SIP_INVITE) 12442 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 12443 if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 12444 sip_alreadygone(p); 12445 if (!p->owner) 12446 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12447 } else if ((resp >= 100) && (resp < 200)) { 12448 if (sipmethod == SIP_INVITE) { 12449 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12450 sip_cancel_destroy(p); 12451 if (find_sdp(req)) 12452 process_sdp(p, req); 12453 if (p->owner) { 12454 /* Queue a progress frame */ 12455 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 12456 } 12457 } 12458 } else 12459 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)); 12460 } 12461 } else { 12462 /* Responses to OUTGOING SIP requests on INCOMING calls 12463 get handled here. As well as out-of-call message responses */ 12464 if (ast_test_flag(req, SIP_PKT_DEBUG)) 12465 ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg); 12466 12467 if (sipmethod == SIP_INVITE && resp == 200) { 12468 /* Tags in early session is replaced by the tag in 200 OK, which is 12469 the final reply to our INVITE */ 12470 char tag[128]; 12471 12472 gettag(req, "To", tag, sizeof(tag)); 12473 ast_string_field_set(p, theirtag, tag); 12474 } 12475 12476 switch(resp) { 12477 case 200: 12478 if (sipmethod == SIP_INVITE) { 12479 handle_response_invite(p, resp, rest, req, seqno); 12480 } else if (sipmethod == SIP_CANCEL) { 12481 if (option_debug) 12482 ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); 12483 12484 /* Wait for 487, then destroy */ 12485 } else if (sipmethod == SIP_NOTIFY) { 12486 /* They got the notify, this is the end */ 12487 if (p->owner) { 12488 if (p->refer) { 12489 if (option_debug) 12490 ast_log(LOG_DEBUG, "Got 200 OK on NOTIFY for transfer\n"); 12491 } else 12492 ast_log(LOG_WARNING, "Notify answer on an owned channel?\n"); 12493 /* ast_queue_hangup(p->owner); Disabled */ 12494 } else { 12495 if (!p->subscribed && !p->refer) 12496 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12497 } 12498 } else if (sipmethod == SIP_BYE) 12499 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12500 else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) 12501 /* We successfully transmitted a message or 12502 a video update request in INFO */ 12503 ; 12504 else if (sipmethod == SIP_BYE) 12505 /* Ok, we're ready to go */ 12506 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12507 break; 12508 case 202: /* Transfer accepted */ 12509 if (sipmethod == SIP_REFER) 12510 handle_response_refer(p, resp, rest, req, seqno); 12511 break; 12512 case 401: /* www-auth */ 12513 case 407: 12514 if (sipmethod == SIP_REFER) 12515 handle_response_refer(p, resp, rest, req, seqno); 12516 else if (sipmethod == SIP_INVITE) 12517 handle_response_invite(p, resp, rest, req, seqno); 12518 else if (sipmethod == SIP_BYE) { 12519 char *auth, *auth2; 12520 12521 auth = (resp == 407 ? "Proxy-Authenticate" : "WWW-Authenticate"); 12522 auth2 = (resp == 407 ? "Proxy-Authorization" : "Authorization"); 12523 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, auth, auth2, sipmethod, 0)) { 12524 ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From")); 12525 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12526 } 12527 } 12528 break; 12529 case 481: /* Call leg does not exist */ 12530 if (sipmethod == SIP_INVITE) { 12531 /* Re-invite failed */ 12532 handle_response_invite(p, resp, rest, req, seqno); 12533 } else if (sipmethod == SIP_BYE) { 12534 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12535 } else if (sipdebug) { 12536 ast_log (LOG_DEBUG, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid); 12537 } 12538 break; 12539 case 501: /* Not Implemented */ 12540 if (sipmethod == SIP_INVITE) 12541 handle_response_invite(p, resp, rest, req, seqno); 12542 else if (sipmethod == SIP_REFER) 12543 handle_response_refer(p, resp, rest, req, seqno); 12544 break; 12545 case 603: /* Declined transfer */ 12546 if (sipmethod == SIP_REFER) { 12547 handle_response_refer(p, resp, rest, req, seqno); 12548 break; 12549 } 12550 /* Fallthrough */ 12551 default: /* Errors without handlers */ 12552 if ((resp >= 100) && (resp < 200)) { 12553 if (sipmethod == SIP_INVITE) { /* re-invite */ 12554 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 12555 sip_cancel_destroy(p); 12556 } 12557 } 12558 if ((resp >= 300) && (resp < 700)) { 12559 if ((option_verbose > 2) && (resp != 487)) 12560 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)); 12561 switch(resp) { 12562 case 488: /* Not acceptable here - codec error */ 12563 case 603: /* Decline */ 12564 case 500: /* Server error */ 12565 case 503: /* Service Unavailable */ 12566 case 504: /* Server timeout */ 12567 12568 if (sipmethod == SIP_INVITE) { /* re-invite failed */ 12569 sip_cancel_destroy(p); 12570 } 12571 break; 12572 } 12573 } 12574 break; 12575 } 12576 } 12577 }
| 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 11663 of file chan_sip.c.
References ast_channel::_state, ast_bridged_channel(), AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, ast_queue_control(), ast_queue_frame(), ast_queue_hangup(), ast_rtp_set_rtptimers_onhold(), ast_sched_del(), ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_string_field_free, ast_test_flag, authenticate(), build_route(), check_pendings(), DEC_CALL_LIMIT, DEC_CALL_RINGING, DEFAULT_TRANS_TIMEOUT, do_proxy_auth(), FALSE, find_sdp(), sip_pvt::flags, get_header(), sip_pvt::initid, INV_CALLING, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, option_debug, sip_pvt::owner, parse_ok_contact(), process_sdp(), PROXY_AUTH, sched, set_address_from_contact(), SIP_ACK, sip_alreadygone(), SIP_ALREADYGONE, sip_cancel_destroy(), sip_handle_t38_reinvite(), SIP_INVITE, SIP_NEEDDESTROY, SIP_OUTGOING, SIP_PENDINGBYE, SIP_PKT_IGNORE, sip_scheddestroy(), sip_tech, sip_tech_info, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_DIRECT, T38_LOCAL_REINVITE, T38_PEER_REINVITE, ast_channel::tech, ast_channel::tech_pvt, transmit_request(), TRUE, ast_channel_tech::type, sip_pvt::udptl, update_call_counter(), WWW_AUTH, and XMIT_UNRELIABLE.
Referenced by handle_response().
11664 { 11665 int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING); 11666 int res = 0; 11667 int reinvite = (p->owner && p->owner->_state == AST_STATE_UP); 11668 struct ast_channel *bridgepeer = NULL; 11669 11670 if (option_debug > 3) { 11671 if (reinvite) 11672 ast_log(LOG_DEBUG, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid); 11673 else 11674 ast_log(LOG_DEBUG, "SIP response %d to standard invite\n", resp); 11675 } 11676 11677 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { /* This call is already gone */ 11678 if (option_debug) 11679 ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); 11680 return; 11681 } 11682 11683 /* Acknowledge sequence number - This only happens on INVITE from SIP-call */ 11684 if (p->initid > -1) { 11685 /* Don't auto congest anymore since we've gotten something useful back */ 11686 ast_sched_del(sched, p->initid); 11687 p->initid = -1; 11688 } 11689 11690 /* RFC3261 says we must treat every 1xx response (but not 100) 11691 that we don't recognize as if it was 183. 11692 */ 11693 if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 183) 11694 resp = 183; 11695 11696 /* Any response between 100 and 199 is PROCEEDING */ 11697 if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING) 11698 p->invitestate = INV_PROCEEDING; 11699 11700 /* Final response, not 200 ? */ 11701 if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA )) 11702 p->invitestate = INV_COMPLETED; 11703 11704 11705 switch (resp) { 11706 case 100: /* Trying */ 11707 case 101: /* Dialog establishment */ 11708 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11709 sip_cancel_destroy(p); 11710 check_pendings(p); 11711 break; 11712 11713 case 180: /* 180 Ringing */ 11714 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11715 sip_cancel_destroy(p); 11716 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 11717 ast_queue_control(p->owner, AST_CONTROL_RINGING); 11718 if (p->owner->_state != AST_STATE_UP) { 11719 ast_setstate(p->owner, AST_STATE_RINGING); 11720 } 11721 } 11722 if (find_sdp(req)) { 11723 p->invitestate = INV_EARLY_MEDIA; 11724 res = process_sdp(p, req); 11725 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 11726 /* Queue a progress frame only if we have SDP in 180 */ 11727 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 11728 } 11729 } 11730 check_pendings(p); 11731 break; 11732 11733 case 183: /* Session progress */ 11734 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11735 sip_cancel_destroy(p); 11736 /* Ignore 183 Session progress without SDP */ 11737 if (find_sdp(req)) { 11738 p->invitestate = INV_EARLY_MEDIA; 11739 res = process_sdp(p, req); 11740 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 11741 /* Queue a progress frame */ 11742 ast_queue_control(p->owner, AST_CONTROL_PROGRESS); 11743 } 11744 } 11745 check_pendings(p); 11746 break; 11747 11748 case 200: /* 200 OK on invite - someone's answering our call */ 11749 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11750 sip_cancel_destroy(p); 11751 p->authtries = 0; 11752 if (find_sdp(req)) { 11753 if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_IGNORE)) 11754 if (!reinvite) 11755 /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ 11756 /* For re-invites, we try to recover */ 11757 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 11758 } 11759 11760 /* Parse contact header for continued conversation */ 11761 /* When we get 200 OK, we know which device (and IP) to contact for this call */ 11762 /* This is important when we have a SIP proxy between us and the phone */ 11763 if (outgoing) { 11764 update_call_counter(p, DEC_CALL_RINGING); 11765 parse_ok_contact(p, req); 11766 if(set_address_from_contact(p)) { 11767 /* Bad contact - we don't know how to reach this device */ 11768 /* We need to ACK, but then send a bye */ 11769 /* OEJ: Possible issue that may need a check: 11770 If we have a proxy route between us and the device, 11771 should we care about resolving the contact 11772 or should we just send it? 11773 */ 11774 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11775 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 11776 } 11777 11778 /* Save Record-Route for any later requests we make on this dialogue */ 11779 build_route(p, req, 1); 11780 } 11781 11782 if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */ 11783 struct sip_pvt *bridgepvt = NULL; 11784 11785 if (!bridgepeer->tech) { 11786 ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n"); 11787 break; 11788 } 11789 if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) { 11790 bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt); 11791 if (bridgepvt->udptl) { 11792 if (p->t38.state == T38_PEER_REINVITE) { 11793 sip_handle_t38_reinvite(bridgepeer, p, 0); 11794 ast_rtp_set_rtptimers_onhold(p->rtp); 11795 if (p->vrtp) 11796 ast_rtp_set_rtptimers_onhold(p->vrtp); /* Turn off RTP timers while we send fax */ 11797 } else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) { 11798 ast_log(LOG_WARNING, "RTP re-inivte after T38 session not handled yet !\n"); 11799 /* Insted of this we should somehow re-invite the other side of the bridge to RTP */ 11800 /* XXXX Should we really destroy this session here, without any response at all??? */ 11801 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11802 } 11803 } else { 11804 if (option_debug > 1) 11805 ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n"); 11806 ast_mutex_lock(&bridgepvt->lock); 11807 bridgepvt->t38.state = T38_DISABLED; 11808 ast_mutex_unlock(&bridgepvt->lock); 11809 if (option_debug) 11810 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type); 11811 p->t38.state = T38_DISABLED; 11812 if (option_debug > 1) 11813 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 11814 } 11815 } else { 11816 /* Other side is not a SIP channel */ 11817 if (option_debug > 1) 11818 ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n"); 11819 p->t38.state = T38_DISABLED; 11820 if (option_debug > 1) 11821 ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 11822 } 11823 } 11824 if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) { 11825 /* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */ 11826 p->t38.state = T38_ENABLED; 11827 if (option_debug) 11828 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 11829 } 11830 11831 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { 11832 if (!reinvite) { 11833 ast_queue_control(p->owner, AST_CONTROL_ANSWER); 11834 } else { /* RE-invite */ 11835 ast_queue_frame(p->owner, &ast_null_frame); 11836 } 11837 } else { 11838 /* It's possible we're getting an 200 OK after we've tried to disconnect 11839 by sending CANCEL */ 11840 /* First send ACK, then send bye */ 11841 if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11842 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 11843 } 11844 /* If I understand this right, the branch is different for a non-200 ACK only */ 11845 p->invitestate = INV_TERMINATED; 11846 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE); 11847 check_pendings(p); 11848 break; 11849 case 407: /* Proxy authentication */ 11850 case 401: /* Www auth */ 11851 /* First we ACK */ 11852 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 11853 if (p->options) 11854 p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH); 11855 11856 /* Then we AUTH */ 11857 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 11858 if (!ast_test_flag(req, SIP_PKT_IGNORE)) { 11859 char *authenticate = (resp == 401 ? "WWW-Authenticate" : "Proxy-Authenticate"); 11860 char *authorization = (resp == 401 ? "Authorization" : "Proxy-Authorization"); 11861 if (p->authtries < MAX_AUTHTRIES) 11862 p->invitestate = INV_CALLING; 11863 if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, authenticate, authorization, SIP_INVITE, 1)) { 11864 ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From")); 11865 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 11866 sip_alreadygone(p); 11867 if (p->owner) 11868 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 11869 } 11870 } 11871 break; 11872 11873 case 403: /* Forbidden */ 11874 /* First we ACK */ 11875 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 11876 ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From")); 11877 if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) 11878 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 11879 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 11880 sip_alreadygone(p); 11881 break; 11882 11883 case 404: /* Not found */ 11884 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 11885 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 11886 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 11887 sip_alreadygone(p); 11888 break; 11889 11890 case 481: /* Call leg does not exist */ 11891 /* Could be REFER caused INVITE with replaces */ 11892 ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid); 11893 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 11894 if (p->owner) 11895 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 11896 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11897 break; 11898 case 487: /* Cancelled transaction */ 11899 /* We have sent CANCEL on an outbound INVITE 11900 This transaction is already scheduled to be killed by sip_hangup(). 11901 */ 11902 transmit_request(p, SIP_ACK, seqno, 0, 0); 11903 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 11904 ast_queue_hangup(p->owner); 11905 else if (!ast_test_flag(req, SIP_PKT_IGNORE)) 11906 update_call_counter(p, DEC_CALL_LIMIT); 11907 break; 11908 case 488: /* Not acceptable here */ 11909 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 11910 if (reinvite && p->udptl) { 11911 /* If this is a T.38 call, we should go back to 11912 audio. If this is an audio call - something went 11913 terribly wrong since we don't renegotiate codecs, 11914 only IP/port . 11915 */ 11916 p->t38.state = T38_DISABLED; 11917 /* Try to reset RTP timers */ 11918 ast_rtp_set_rtptimers_onhold(p->rtp); 11919 ast_log(LOG_ERROR, "Got error on T.38 re-invite. Bad configuration. Peer needs to have T.38 disabled.\n"); 11920 11921 /*! \bug Is there any way we can go back to the audio call on both 11922 sides here? 11923 */ 11924 /* While figuring that out, hangup the call */ 11925 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 11926 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 11927 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 11928 } else { 11929 /* We can't set up this call, so give up */ 11930 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 11931 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 11932 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 11933 } 11934 break; 11935 case 491: /* Pending */ 11936 /* we really should have to wait a while, then retransmit */ 11937 /* We should support the retry-after at some point */ 11938 /* At this point, we treat this as a congestion */ 11939 transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE); 11940 if (p->owner && !ast_test_flag(req, SIP_PKT_IGNORE)) 11941 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 11942 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 11943 break; 11944 11945 case 501: /* Not implemented */ 11946 transmit_request(p, SIP_ACK, seqno, 0, 0); 11947 if (p->owner) 11948 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 11949 break; 11950 } 11951 }
| static void handle_response_peerpoke | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| struct sip_request * | req | |||
| ) | [static] |
Handle qualification responses (OPTIONS).
Definition at line 12145 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, sip_peer::call, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, EVENT_FLAG_SYSTEM, sip_pvt::flags, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::maxms, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::relatedpeer, s, sched, SIP_NEEDDESTROY, and sip_poke_peer_s().
Referenced by handle_response().
12146 { 12147 struct sip_peer *peer = p->relatedpeer; 12148 int statechanged, is_reachable, was_reachable; 12149 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps); 12150 12151 /* 12152 * Compute the response time to a ping (goes in peer->lastms.) 12153 * -1 means did not respond, 0 means unknown, 12154 * 1..maxms is a valid response, >maxms means late response. 12155 */ 12156 if (pingtime < 1) /* zero = unknown, so round up to 1 */ 12157 pingtime = 1; 12158 12159 /* Now determine new state and whether it has changed. 12160 * Use some helper variables to simplify the writing 12161 * of the expressions. 12162 */ 12163 was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms; 12164 is_reachable = pingtime <= peer->maxms; 12165 statechanged = peer->lastms == 0 /* yes, unknown before */ 12166 || was_reachable != is_reachable; 12167 12168 peer->lastms = pingtime; 12169 peer->call = NULL; 12170 if (statechanged) { 12171 const char *s = is_reachable ? "Reachable" : "Lagged"; 12172 12173 ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n", 12174 peer->name, s, pingtime, peer->maxms); 12175 ast_device_state_changed("SIP/%s", peer->name); 12176 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", 12177 "Peer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n", 12178 peer->name, s, pingtime); 12179 } 12180 12181 if (peer->pokeexpire > -1) 12182 ast_sched_del(sched, peer->pokeexpire); 12183 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12184 12185 /* Try again eventually */ 12186 peer->pokeexpire = ast_sched_add(sched, 12187 is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK, 12188 sip_poke_peer_s, peer); 12189 }
| static void handle_response_refer | ( | struct sip_pvt * | p, | |
| int | resp, | |||
| char * | rest, | |||
| struct sip_request * | req, | |||
| int | seqno | |||
| ) | [static] |
Definition at line 11956 of file chan_sip.c.
References AST_CONTROL_CONGESTION, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_set_flag, ast_strlen_zero(), sip_pvt::authtries, do_proxy_auth(), sip_pvt::flags, get_header(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, option_debug, sip_pvt::owner, sip_pvt::recv, sip_pvt::refer, REFER_ACCEPTED, REFER_FAILED, REFER_NOAUTH, sip_refer::refer_to, SIP_NEEDDESTROY, SIP_REFER, and sip_refer::status.
Referenced by handle_response().
11957 { 11958 char *auth = "Proxy-Authenticate"; 11959 char *auth2 = "Proxy-Authorization"; 11960 11961 /* If no refer structure exists, then do nothing */ 11962 if (!p->refer) 11963 return; 11964 11965 switch (resp) { 11966 case 202: /* Transfer accepted */ 11967 /* We need to do something here */ 11968 /* The transferee is now sending INVITE to target */ 11969 p->refer->status = REFER_ACCEPTED; 11970 /* Now wait for next message */ 11971 if (option_debug > 2) 11972 ast_log(LOG_DEBUG, "Got 202 accepted on transfer\n"); 11973 /* We should hang along, waiting for NOTIFY's here */ 11974 break; 11975 11976 case 401: /* Not www-authorized on SIP method */ 11977 case 407: /* Proxy auth */ 11978 if (ast_strlen_zero(p->authname)) { 11979 ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n", 11980 ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port)); 11981 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 11982 } 11983 if (resp == 401) { 11984 auth = "WWW-Authenticate"; 11985 auth2 = "Authorization"; 11986 } 11987 if ((p->authtries > 1) || do_proxy_auth(p, req, auth, auth2, SIP_REFER, 0)) { 11988 ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From")); 11989 p->refer->status = REFER_NOAUTH; 11990 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 11991 } 11992 break; 11993 case 481: /* Call leg does not exist */ 11994 11995 /* A transfer with Replaces did not work */ 11996 /* OEJ: We should Set flag, cancel the REFER, go back 11997 to original call - but right now we can't */ 11998 ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid); 11999 if (p->owner) 12000 ast_queue_control(p->owner, AST_CONTROL_CONGESTION); 12001 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12002 break; 12003 12004 case 500: /* Server error */ 12005 case 501: /* Method not implemented */ 12006 /* Return to the current call onhold */ 12007 /* Status flag needed to be reset */ 12008 ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to); 12009 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12010 p->refer->status = REFER_FAILED; 12011 break; 12012 case 603: /* Transfer declined */ 12013 ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to); 12014 p->refer->status = REFER_FAILED; 12015 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12016 break; 12017 } 12018 }
| 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 12021 of file chan_sip.c.
References __get_header(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_strlen_zero(), ASTOBJ_UNREF, sip_pvt::authtries, sip_registry::call, DEFAULT_TRANS_TIMEOUT, do_register_auth(), EVENT_FLAG_SYSTEM, sip_registry::expire, EXPIRY_GUARD_LIMIT, EXPIRY_GUARD_MIN, EXPIRY_GUARD_PCT, EXPIRY_GUARD_SECS, sip_pvt::flags, get_header(), sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_event(), MAX, MAX_AUTHTRIES, option_debug, sip_registry::refresh, REG_STATE_REGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), sip_registry::regtime, sched, SIP_NEEDDESTROY, sip_registry_destroy(), sip_reregister(), sip_scheddestroy(), sipdebug, strcasestr(), and sip_registry::timeout.
Referenced by handle_response().
12022 { 12023 int expires, expires_ms; 12024 struct sip_registry *r; 12025 r=p->registry; 12026 12027 switch (resp) { 12028 case 401: /* Unauthorized */ 12029 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "WWW-Authenticate", "Authorization")) { 12030 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries); 12031 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12032 } 12033 break; 12034 case 403: /* Forbidden */ 12035 ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname); 12036 if (global_regattempts_max) 12037 p->registry->regattempts = global_regattempts_max+1; 12038 ast_sched_del(sched, r->timeout); 12039 r->timeout = -1; 12040 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12041 break; 12042 case 404: /* Not found */ 12043 ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username,p->registry->hostname); 12044 if (global_regattempts_max) 12045 p->registry->regattempts = global_regattempts_max+1; 12046 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12047 r->call = NULL; 12048 ast_sched_del(sched, r->timeout); 12049 r->timeout = -1; 12050 break; 12051 case 407: /* Proxy auth */ 12052 if ((p->authtries == MAX_AUTHTRIES) || do_register_auth(p, req, "Proxy-Authenticate", "Proxy-Authorization")) { 12053 ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries); 12054 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12055 } 12056 break; 12057 case 479: /* SER: Not able to process the URI - address is wrong in register*/ 12058 ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username,p->registry->hostname); 12059 if (global_regattempts_max) 12060 p->registry->regattempts = global_regattempts_max+1; 12061 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12062 r->call = NULL; 12063 ast_sched_del(sched, r->timeout); 12064 r->timeout = -1; 12065 break; 12066 case 200: /* 200 OK */ 12067 if (!r) { 12068 ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n"); 12069 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 12070 return 0; 12071 } 12072 12073 r->regstate = REG_STATE_REGISTERED; 12074 r->regtime = time(NULL); /* Reset time of last succesful registration */ 12075 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate)); 12076 r->regattempts = 0; 12077 if (option_debug) 12078 ast_log(LOG_DEBUG, "Registration successful\n"); 12079 if (r->timeout > -1) { 12080 if (option_debug) 12081 ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout); 12082 ast_sched_del(sched, r->timeout); 12083 } 12084 r->timeout=-1; 12085 r->call = NULL; 12086 p->registry = NULL; 12087 /* Let this one hang around until we have all the responses */ 12088 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 12089 /* ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); */ 12090 12091 /* set us up for re-registering */ 12092 /* figure out how long we got registered for */ 12093 if (r->expire > -1) 12094 ast_sched_del(sched, r->expire); 12095 /* according to section 6.13 of RFC, contact headers override 12096 expires headers, so check those first */ 12097 expires = 0; 12098 12099 /* XXX todo: try to save the extra call */ 12100 if (!ast_strlen_zero(get_header(req, "Contact"))) { 12101 const char *contact = NULL; 12102 const char *tmptmp = NULL; 12103 int start = 0; 12104 for(;;) { 12105 contact = __get_header(req, "Contact", &start); 12106 /* this loop ensures we get a contact header about our register request */ 12107 if(!ast_strlen_zero(contact)) { 12108 if( (tmptmp=strstr(contact, p->our_contact))) { 12109 contact=tmptmp; 12110 break; 12111 } 12112 } else 12113 break; 12114 } 12115 tmptmp = strcasestr(contact, "expires="); 12116 if (tmptmp) { 12117 if (sscanf(tmptmp + 8, "%d;", &expires) != 1) 12118 expires = 0; 12119 } 12120 12121 } 12122 if (!expires) 12123 expires=atoi(get_header(req, "expires")); 12124 if (!expires) 12125 expires=default_expiry; 12126 12127 expires_ms = expires * 1000; 12128 if (expires <= EXPIRY_GUARD_LIMIT) 12129 expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT),EXPIRY_GUARD_MIN); 12130 else 12131 expires_ms -= EXPIRY_GUARD_SECS * 1000; 12132 if (sipdebug) 12133 ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 12134 12135 r->refresh= (int) expires_ms / 1000; 12136 12137 /* Schedule re-registration before we expire */ 12138 r->expire=ast_sched_add(sched, expires_ms, sip_reregister, r); 12139 ASTOBJ_UNREF(r, sip_registry_destroy); 12140 } 12141 return 1; 12142 }
| 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 3228 of file chan_sip.c.
References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CHAN_NOT_IMPLEMENTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_ROUTE_TRANSIT_NET, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL_UNSPECIFIED, AST_CAUSE_NOTDEFINED, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNALLOCATED, AST_CAUSE_USER_BUSY, ast_log(), LOG_DEBUG, and option_debug.
Referenced by sip_hangup().
03229 { 03230 switch (cause) { 03231 case AST_CAUSE_UNALLOCATED: /* 1 */ 03232 case AST_CAUSE_NO_ROUTE_DESTINATION: /* 3 IAX2: Can't find extension in context */ 03233 case AST_CAUSE_NO_ROUTE_TRANSIT_NET: /* 2 */ 03234 return "404 Not Found"; 03235 case AST_CAUSE_CONGESTION: /* 34 */ 03236 case AST_CAUSE_SWITCH_CONGESTION: /* 42 */ 03237 return "503 Service Unavailable"; 03238 case AST_CAUSE_NO_USER_RESPONSE: /* 18 */ 03239 return "408 Request Timeout"; 03240 case AST_CAUSE_NO_ANSWER: /* 19 */ 03241 return "480 Temporarily unavailable"; 03242 case AST_CAUSE_CALL_REJECTED: /* 21 */ 03243 return "403 Forbidden"; 03244 case AST_CAUSE_NUMBER_CHANGED: /* 22 */ 03245 return "410 Gone"; 03246 case AST_CAUSE_NORMAL_UNSPECIFIED: /* 31 */ 03247 return "480 Temporarily unavailable"; 03248 case AST_CAUSE_INVALID_NUMBER_FORMAT: 03249 return "484 Address incomplete"; 03250 case AST_CAUSE_USER_BUSY: 03251 return "486 Busy here"; 03252 case AST_CAUSE_FAILURE: 03253 return "500 Server internal failure"; 03254 case AST_CAUSE_FACILITY_REJECTED: /* 29 */ 03255 return "501 Not Implemented"; 03256 case AST_CAUSE_CHAN_NOT_IMPLEMENTED: 03257 return "503 Service Unavailable"; 03258 /* Used in chan_iax2 */ 03259 case AST_CAUSE_DESTINATION_OUT_OF_ORDER: 03260 return "502 Bad Gateway"; 03261 case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */ 03262 return "488 Not Acceptable Here"; 03263 03264 case AST_CAUSE_NOTDEFINED: 03265 default: 03266 if (option_debug) 03267 ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause); 03268 return NULL; 03269 } 03270 03271 /* Never reached */ 03272 return 0; 03273 }
| static int hangup_sip2cause | ( | int | cause | ) | [static] |
Convert SIP hangup causes to Asterisk hangup causes.
Definition at line 3116 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().
03117 { 03118 /* Possible values taken from causes.h */ 03119 03120 switch(cause) { 03121 case 401: /* Unauthorized */ 03122 return AST_CAUSE_CALL_REJECTED; 03123 case 403: /* Not found */ 03124 return AST_CAUSE_CALL_REJECTED; 03125 case 404: /* Not found */ 03126 return AST_CAUSE_UNALLOCATED; 03127 case 405: /* Method not allowed */ 03128 return AST_CAUSE_INTERWORKING; 03129 case 407: /* Proxy authentication required */ 03130 return AST_CAUSE_CALL_REJECTED; 03131 case 408: /* No reaction */ 03132 return AST_CAUSE_NO_USER_RESPONSE; 03133 case 409: /* Conflict */ 03134 return AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 03135 case 410: /* Gone */ 03136 return AST_CAUSE_UNALLOCATED; 03137 case 411: /* Length required */ 03138 return AST_CAUSE_INTERWORKING; 03139 case 413: /* Request entity too large */ 03140 return AST_CAUSE_INTERWORKING; 03141 case 414: /* Request URI too large */ 03142 return AST_CAUSE_INTERWORKING; 03143 case 415: /* Unsupported media type */ 03144 return AST_CAUSE_INTERWORKING; 03145 case 420: /* Bad extension */ 03146 return AST_CAUSE_NO_ROUTE_DESTINATION; 03147 case 480: /* No answer */ 03148 return AST_CAUSE_NO_ANSWER; 03149 case 481: /* No answer */ 03150 return AST_CAUSE_INTERWORKING; 03151 case 482: /* Loop detected */ 03152 return AST_CAUSE_INTERWORKING; 03153 case 483: /* Too many hops */ 03154 return AST_CAUSE_NO_ANSWER; 03155 case 484: /* Address incomplete */ 03156 return AST_CAUSE_INVALID_NUMBER_FORMAT; 03157 case 485: /* Ambigous */ 03158 return AST_CAUSE_UNALLOCATED; 03159 case 486: /* Busy everywhere */ 03160 return AST_CAUSE_BUSY; 03161 case 487: /* Request terminated */ 03162 return AST_CAUSE_INTERWORKING; 03163 case 488: /* No codecs approved */ 03164 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03165 case 491: /* Request pending */ 03166 return AST_CAUSE_INTERWORKING; 03167 case 493: /* Undecipherable */ 03168 return AST_CAUSE_INTERWORKING; 03169 case 500: /* Server internal failure */ 03170 return AST_CAUSE_FAILURE; 03171 case 501: /* Call rejected */ 03172 return AST_CAUSE_FACILITY_REJECTED; 03173 case 502: 03174 return AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03175 case 503: /* Service unavailable */ 03176 return AST_CAUSE_CONGESTION; 03177 case 504: /* Gateway timeout */ 03178 return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE; 03179 case 505: /* SIP version not supported */ 03180 return AST_CAUSE_INTERWORKING; 03181 case 600: /* Busy everywhere */ 03182 return AST_CAUSE_USER_BUSY; 03183 case 603: /* Decline */ 03184 return AST_CAUSE_CALL_REJECTED; 03185 case 604: /* Does not exist anywhere */ 03186 return AST_CAUSE_UNALLOCATED; 03187 case 606: /* Not acceptable */ 03188 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 03189 default: 03190 return AST_CAUSE_NORMAL; 03191 } 03192 /* Never reached */ 03193 return 0; 03194 }
| static int init_req | ( | struct sip_request * | req, | |
| int | sipmethod, | |||
| const char * | recip | |||
| ) | [static] |
Initialize SIP request.
Definition at line 5571 of file chan_sip.c.
References sip_methods, and cfsip_methods::text.
05572 { 05573 /* Initialize a request */ 05574 memset(req, 0, sizeof(*req)); 05575 req->method = sipmethod; 05576 req->header[0] = req->data; 05577 snprintf(req->header[0], sizeof(req->data), "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip); 05578 req->len = strlen(req->header[0]); 05579 req->headers++; 05580 return 0; 05581 }
| static int init_resp | ( | struct sip_request * | resp, | |
| const char * | msg | |||
| ) | [static] |
Initialize SIP response, based on SIP request.
Definition at line 5558 of file chan_sip.c.
References SIP_RESPONSE.
05559 { 05560 /* Initialize a response */ 05561 memset(resp, 0, sizeof(*resp)); 05562 resp->method = SIP_RESPONSE; 05563 resp->header[0] = resp->data; 05564 snprintf(resp->header[0], sizeof(resp->data), "SIP/2.0 %s\r\n", msg); 05565 resp->len = strlen(resp->header[0]); 05566 resp->headers++; 05567 return 0; 05568 }
| 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 1619 of file chan_sip.c.
References ast_log(), ast_test_flag, ast_verbose(), copy_request(), sip_request::headers, sip_pvt::initreq, sip_request::lines, LOG_DEBUG, option_debug, parse_request(), and SIP_PKT_DEBUG.
Referenced by transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_reinvite_with_sdp(), transmit_reinvite_with_t38_sdp(), and transmit_sip_request().
01620 { 01621 if (p->initreq.headers && option_debug) { 01622 ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid); 01623 } 01624 /* Use this as the basis */ 01625 copy_request(&p->initreq, req); 01626 parse_request(&p->initreq); 01627 if (ast_test_flag(req, SIP_PKT_DEBUG)) 01628 ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 01629 }
| static void initreqprep | ( | struct sip_request * | req, | |
| struct sip_pvt * | p, | |||
| int | sipmethod | |||
| ) | [static] |
Initiate new SIP request to peer/user.
Definition at line 6647 of file chan_sip.c.
References add_header(), ast_build_string(), AST_DIGIT_ANYNUM, ast_inet_ntoa(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_encode(), build_contact(), build_rpid(), CALLERID_UNKNOWN, sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, DEFAULT_MAX_FORWARDS, exten, sip_pvt::flags, init_req(), sip_pvt::lastmsg, sip_pvt::ocseq, sip_pvt::options, sip_pvt::ourip, ourport, sip_pvt::owner, s, S_OR, sip_pvt::sa, SIP_INVITE, sip_methods, SIP_NOTIFY, SIP_SENDRPID, SIP_USEREQPHONE, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_invite_param::uri_options, and sip_invite_param::vxml_url.
Referenced by sip_notify(), transmit_invite(), and transmit_notify_with_mwi().
06648 { 06649 char invite_buf[256] = ""; 06650 char *invite = invite_buf; 06651 size_t invite_max = sizeof(invite_buf); 06652 char from[256]; 06653 char to[256]; 06654 char tmp[BUFSIZ/2]; 06655 char tmp2[BUFSIZ/2]; 06656 const char *l = NULL, *n = NULL; 06657 const char *urioptions = ""; 06658 06659 if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) { 06660 const char *s = p->username; /* being a string field, cannot be NULL */ 06661 06662 /* Test p->username against allowed characters in AST_DIGIT_ANY 06663 If it matches the allowed characters list, then sipuser = ";user=phone" 06664 If not, then sipuser = "" 06665 */ 06666 /* + is allowed in first position in a tel: uri */ 06667 if (*s == '+') 06668 s++; 06669 for (; *s; s++) { 06670 if (!strchr(AST_DIGIT_ANYNUM, *s) ) 06671 break; 06672 } 06673 /* If we have only digits, add ;user=phone to the uri */ 06674 if (*s) 06675 urioptions = ";user=phone"; 06676 } 06677 06678 06679 snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text); 06680 06681 if (p->owner) { 06682 l = p->owner->cid.cid_num; 06683 n = p->owner->cid.cid_name; 06684 } 06685 /* if we are not sending RPID and user wants his callerid restricted */ 06686 if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) && 06687 ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) { 06688 l = CALLERID_UNKNOWN; 06689 n = l; 06690 } 06691 if (ast_strlen_zero(l)) 06692 l = default_callerid; 06693 if (ast_strlen_zero(n)) 06694 n = l; 06695 /* Allow user to be overridden */ 06696 if (!ast_strlen_zero(p->fromuser)) 06697 l = p->fromuser; 06698 else /* Save for any further attempts */ 06699 ast_string_field_set(p, fromuser, l); 06700 06701 /* Allow user to be overridden */ 06702 if (!ast_strlen_zero(p->fromname)) 06703 n = p->fromname; 06704 else /* Save for any further attempts */ 06705 ast_string_field_set(p, fromname, n); 06706 06707 if (pedanticsipchecking) { 06708 ast_uri_encode(n, tmp, sizeof(tmp), 0); 06709 n = tmp; 06710 ast_uri_encode(l, tmp2, sizeof(tmp2), 0); 06711 l = tmp2; 06712 } 06713 06714 if (ourport != STANDARD_SIP_PORT && ast_strlen_zero(p->fromdomain)) 06715 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); 06716 else 06717 snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag); 06718 06719 /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */ 06720 if (!ast_strlen_zero(p->fullcontact)) { 06721 /* If we have full contact, trust it */ 06722 ast_build_string(&invite, &invite_max, "%s", p->fullcontact); 06723 } else { 06724 /* Otherwise, use the username while waiting for registration */ 06725 ast_build_string(&invite, &invite_max, "sip:"); 06726 if (!ast_strlen_zero(p->username)) { 06727 n = p->username; 06728 if (pedanticsipchecking) { 06729 ast_uri_encode(n, tmp, sizeof(tmp), 0); 06730 n = tmp; 06731 } 06732 ast_build_string(&invite, &invite_max, "%s@", n); 06733 } 06734 ast_build_string(&invite, &invite_max, "%s", p->tohost); 06735 if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT) 06736 ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port)); 06737 ast_build_string(&invite, &invite_max, "%s", urioptions); 06738 } 06739 06740 /* If custom URI options have been provided, append them */ 06741 if (p->options && p->options->uri_options) 06742 ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options); 06743 06744 ast_string_field_set(p, uri, invite_buf); 06745 06746 if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 06747 /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ 06748 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", p->uri, p->theirtag); 06749 } else if (p->options && p->options->vxml_url) { 06750 /* If there is a VXML URL append it to the SIP URL */ 06751 snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); 06752 } else 06753 snprintf(to, sizeof(to), "<%s>", p->uri); 06754 06755 init_req(req, sipmethod, p->uri); 06756 snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_methods[sipmethod].text); 06757 06758 add_header(req, "Via", p->via); 06759 /* SLD: FIXME?: do Route: here too? I think not cos this is the first request. 06760 * OTOH, then we won't have anything in p->route anyway */ 06761 /* Build Remote Party-ID and From */ 06762 if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) { 06763 build_rpid(p); 06764 add_header(req, "From", p->rpid_from); 06765 } else 06766 add_header(req, "From", from); 06767 add_header(req, "To", to); 06768 ast_string_field_set(p, exten, l); 06769 build_contact(p); 06770 add_header(req, "Contact", p->our_contact); 06771 add_header(req, "Call-ID", p->callid); 06772 add_header(req, "CSeq", tmp); 06773 if (!ast_strlen_zero(global_useragent)) 06774 add_header(req, "User-Agent", global_useragent); 06775 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 06776 if (!ast_strlen_zero(p->rpid)) 06777 add_header(req, "Remote-Party-ID", p->rpid); 06778 }
| static const char * insecure2str | ( | int | port, | |
| int | invite | |||
| ) | const [static] |
Convert Insecure setting to printable string.
Definition at line 9724 of file chan_sip.c.
Referenced by _sip_show_peer().
09725 { 09726 if (port && invite) 09727 return "port,invite"; 09728 else if (port) 09729 return "port"; 09730 else if (invite) 09731 return "invite"; 09732 else 09733 return "no"; 09734 }
| static void list_route | ( | struct sip_route * | route | ) | [static] |
List all routes - mostly for debugging.
Definition at line 7922 of file chan_sip.c.
References ast_verbose(), sip_route::hop, and sip_route::next.
Referenced by build_route().
07923 { 07924 if (!route) 07925 ast_verbose("list_route: no route\n"); 07926 else { 07927 for (;route; route = route->next) 07928 ast_verbose("list_route: hop: <%s>\n", route->hop); 07929 } 07930 }
| static int load_module | ( | void | ) | [static] |
PBX load module - initialization.
Definition at line 17400 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.
17401 { 17402 ASTOBJ_CONTAINER_INIT(&userl); /* User object list */ 17403 ASTOBJ_CONTAINER_INIT(&peerl); /* Peer object list */ 17404 ASTOBJ_CONTAINER_INIT(®l); /* Registry object list */ 17405 17406 if (!(sched = sched_context_create())) { 17407 ast_log(LOG_ERROR, "Unable to create scheduler context\n"); 17408 return AST_MODULE_LOAD_FAILURE; 17409 } 17410 17411 if (!(io = io_context_create())) { 17412 ast_log(LOG_ERROR, "Unable to create I/O context\n"); 17413 sched_context_destroy(sched); 17414 return AST_MODULE_LOAD_FAILURE; 17415 } 17416 17417 sip_reloadreason = CHANNEL_MODULE_LOAD; 17418 17419 if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */ 17420 return AST_MODULE_LOAD_DECLINE; 17421 17422 /* Make sure we can register our sip channel type */ 17423 if (ast_channel_register(&sip_tech)) { 17424 ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); 17425 io_context_destroy(io); 17426 sched_context_destroy(sched); 17427 return AST_MODULE_LOAD_FAILURE; 17428 } 17429 17430 /* Register all CLI functions for SIP */ 17431 ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry)); 17432 17433 /* Tell the RTP subdriver that we're here */ 17434 ast_rtp_proto_register(&sip_rtp); 17435 17436 /* Tell the UDPTL subdriver that we're here */ 17437 ast_udptl_proto_register(&sip_udptl); 17438 17439 /* Register dialplan applications */ 17440 ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); 17441 ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); 17442 17443 /* Register dialplan functions */ 17444 ast_custom_function_register(&sip_header_function); 17445 ast_custom_function_register(&sippeer_function); 17446 ast_custom_function_register(&sipchaninfo_function); 17447 ast_custom_function_register(&checksipdomain_function); 17448 17449 /* Register manager commands */ 17450 ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM, manager_sip_show_peers, 17451 "List SIP peers (text format)", mandescr_show_peers); 17452 ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM, manager_sip_show_peer, 17453 "Show SIP peer (text format)", mandescr_show_peer); 17454 17455 sip_poke_all_peers(); 17456 sip_send_all_registers(); 17457 17458 /* And start the monitor for the first time */ 17459 restart_monitor(); 17460 17461 return AST_MODULE_LOAD_SUCCESS; 17462 }
| 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 13694 of file chan_sip.c.
References ast_channel::_state, append_history, ast_bridged_channel(), ast_channel_unlock, ast_clear_flag, ast_hangup(), ast_log(), ast_mutex_unlock(), ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, attempt_transfer(), sip_dual::chan1, sip_dual::chan2, sip_pvt::flags, get_sip_pvt_byid_locked(), sip_refer::localtransfer, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::owner, sip_pvt::refer, REFER_200OK, REFER_FAILED, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, sipdebug, sip_refer::status, transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by handle_request_refer().
13695 { 13696 struct sip_dual target; /* Chan 1: Call from tranferer to Asterisk */ 13697 /* Chan 2: Call from Asterisk to target */ 13698 int res = 0; 13699 struct sip_pvt *targetcall_pvt; 13700 13701 /* Check if the call ID of the replaces header does exist locally */ 13702 if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 13703 transferer->refer->replaces_callid_fromtag))) { 13704 if (transferer->refer->localtransfer) { 13705 /* We did not find the refered call. Sorry, can't accept then */ 13706 transmit_response(transferer, "202 Accepted", req); 13707 /* Let's fake a response from someone else in order 13708 to follow the standard */ 13709 transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE); 13710 append_history(transferer, "Xfer", "Refer failed"); 13711 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 13712 transferer->refer->status = REFER_FAILED; 13713 return -1; 13714 } 13715 /* Fall through for remote transfers that we did not find locally */ 13716 if (option_debug > 2) 13717 ast_log(LOG_DEBUG, "SIP attended transfer: Not our call - generating INVITE with replaces\n"); 13718 return 0; 13719 } 13720 13721 /* Ok, we can accept this transfer */ 13722 transmit_response(transferer, "202 Accepted", req); 13723 append_history(transferer, "Xfer", "Refer accepted"); 13724 if (!targetcall_pvt->owner) { /* No active channel */ 13725 if (option_debug > 3) 13726 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No owner of target call\n"); 13727 /* Cancel transfer */ 13728 transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE); 13729 append_history(transferer, "Xfer", "Refer failed"); 13730 ast_clear_flag(&transferer->flags[0], SIP_GOTREFER); 13731 transferer->refer->status = REFER_FAILED; 13732 ast_mutex_unlock(&targetcall_pvt->lock); 13733 ast_channel_unlock(current->chan1); 13734 ast_channel_unlock(targetcall_pvt->owner); 13735 return -1; 13736 } 13737 13738 /* We have a channel, find the bridge */ 13739 target.chan1 = targetcall_pvt->owner; /* Transferer to Asterisk */ 13740 target.chan2 = ast_bridged_channel(targetcall_pvt->owner); /* Asterisk to target */ 13741 13742 if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) { 13743 /* Wrong state of new channel */ 13744 if (option_debug > 3) { 13745 if (target.chan2) 13746 ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state)); 13747 else if (target.chan1->_state != AST_STATE_RING) 13748 ast_log(LOG_DEBUG, "SIP attended transfer: Error: No target channel\n"); 13749 else 13750 ast_log(LOG_DEBUG, "SIP attended transfer: Attempting transfer in ringing state\n"); 13751 } 13752 } 13753 13754 /* Transfer */ 13755 if (option_debug > 3 && sipdebug) { 13756 if (current->chan2) /* We have two bridges */ 13757 ast_log(LOG_DEBUG, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name); 13758 else /* One bridge, propably transfer of IVR/voicemail etc */ 13759 ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name); 13760 } 13761 13762 ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Delay hangup */ 13763 13764 /* Perform the transfer */ 13765 res = attempt_transfer(current, &target); 13766 ast_mutex_unlock(&targetcall_pvt->lock); 13767 if (res) { 13768 /* Failed transfer */ 13769 /* Could find better message, but they will get the point */ 13770 transmit_notify_with_sipfrag(transferer, seqno, "486 Busy", TRUE); 13771 append_history(transferer, "Xfer", "Refer failed"); 13772 if (targetcall_pvt->owner) 13773 ast_channel_unlock(targetcall_pvt->owner); 13774 /* Right now, we have to hangup, sorry. Bridge is destroyed */ 13775 ast_hangup(transferer->owner); 13776 } else { 13777 /* Transfer succeeded! */ 13778 13779 /* Tell transferer that we're done. */ 13780 transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE); 13781 append_history(transferer, "Xfer", "Refer succeeded"); 13782 transferer->refer->status = REFER_200OK; 13783 if (targetcall_pvt->owner) { 13784 if (option_debug) 13785 ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name); 13786 ast_channel_unlock(targetcall_pvt->owner); 13787 } 13788 } 13789 return 1; 13790 }
| 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 4524 of file chan_sip.c.
References t.
Referenced by sipsock_read().
04525 { 04526 int h = 0, t = 0; 04527 int lws = 0; 04528 04529 for (; h < len;) { 04530 /* Eliminate all CRs */ 04531 if (msgbuf[h] == '\r') { 04532 h++; 04533 continue; 04534 } 04535 /* Check for end-of-line */ 04536 if (msgbuf[h] == '\n') { 04537 /* Check for end-of-message */ 04538 if (h + 1 == len) 04539 break; 04540 /* Check for a continuation line */ 04541 if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 04542 /* Merge continuation line */ 04543 h++; 04544 continue; 04545 } 04546 /* Propagate LF and start new line */ 04547 msgbuf[t++] = msgbuf[h++]; 04548 lws = 0; 04549 continue; 04550 } 04551 if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 04552 if (lws) { 04553 h++; 04554 continue; 04555 } 04556 msgbuf[t++] = msgbuf[h++]; 04557 lws = 1; 04558 continue; 04559 } 04560 msgbuf[t++] = msgbuf[h++]; 04561 if (lws) 04562 lws = 0; 04563 } 04564 msgbuf[t] = '\0'; 04565 return t; 04566 }
| static void make_our_tag | ( | char * | tagbuf, | |
| size_t | len | |||
| ) | [static] |
Make our SIP dialog tag.
Definition at line 4196 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().
04197 { 04198 snprintf(tagbuf, len, "as%08lx", ast_random()); 04199 }
| static int manager_sip_show_peer | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show SIP peers in the manager API.
Definition at line 9969 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().
09970 { 09971 const char *a[4]; 09972 const char *peer; 09973 int ret; 09974 09975 peer = astman_get_header(m,"Peer"); 09976 if (ast_strlen_zero(peer)) { 09977 astman_send_error(s, m, "Peer: <name> missing.\n"); 09978 return 0; 09979 } 09980 a[0] = "sip"; 09981 a[1] = "show"; 09982 a[2] = "peer"; 09983 a[3] = peer; 09984 09985 ret = _sip_show_peer(1, -1, s, m, 4, a); 09986 astman_append(s, "\r\n\r\n" ); 09987 return ret; 09988 }
| static int manager_sip_show_peers | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show SIP peers in the manager API.
Definition at line 9520 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().
09521 { 09522 const char *id = astman_get_header(m,"ActionID"); 09523 const char *a[] = {"sip", "show", "peers"}; 09524 char idtext[256] = ""; 09525 int total = 0; 09526 09527 if (!ast_strlen_zero(id)) 09528 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 09529 09530 astman_send_ack(s, m, "Peer status list will follow"); 09531 /* List the peers in separate manager events */ 09532 _sip_show_peers(-1, &total, s, m, 3, a); 09533 /* Send final confirmation */ 09534 astman_append(s, 09535 "Event: PeerlistComplete\r\n" 09536 "ListItems: %d\r\n" 09537 "%s" 09538 "\r\n", total, idtext); 09539 return 0; 09540 }
| 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 1645 of file chan_sip.c.
References len, sip_methods, and text.
Referenced by __sip_semi_ack(), and find_sip_method().
01646 { 01647 int len = strlen(sip_methods[id].text); 01648 int l_name = name ? strlen(name) : 0; 01649 /* true if the string is long enough, and ends with whitespace, and matches */ 01650 return (l_name >= len && name[len] < 33 && 01651 !strncasecmp(sip_methods[id].text, name, len)); 01652 }
| static char * nat2str | ( | int | nat | ) | const [static] |
Convert NAT setting to text string.
Definition at line 9423 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().
09424 { 09425 switch(nat) { 09426 case SIP_NAT_NEVER: 09427 return "No"; 09428 case SIP_NAT_ROUTE: 09429 return "Route"; 09430 case SIP_NAT_ALWAYS: 09431 return "Always"; 09432 case SIP_NAT_RFC3581: 09433 return "RFC3581"; 09434 default: 09435 return "Unknown"; 09436 } 09437 }
| static void parse_copy | ( | struct sip_request * | dst, | |
| const struct sip_request * | src | |||
| ) | [static] |
Copy SIP request, parse it.
Definition at line 2138 of file chan_sip.c.
References sip_request::data, sip_request::len, and parse_request().
Referenced by send_request(), and send_response().
02139 { 02140 memset(dst, 0, sizeof(*dst)); 02141 memcpy(dst->data, src->data, sizeof(dst->data)); 02142 dst->len = src->len; 02143 parse_request(dst); 02144 }
| static void parse_moved_contact | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Parse 302 Moved temporalily response.
Definition at line 11598 of file chan_sip.c.
References ast_log(), ast_string_field_build, ast_string_field_set, ast_test_flag, sip_pvt::flags, get_header(), get_in_brackets(), LOG_DEBUG, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), s, SIP_PROMISCREDIR, and strsep().
Referenced by handle_response().
11599 { 11600 char tmp[BUFSIZ]; 11601 char *s, *e; 11602 char *domain; 11603 11604 ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp)); 11605 s = get_in_brackets(tmp); 11606 s = strsep(&s, ";"); /* strip ; and beyond */ 11607 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 11608 if (!strncasecmp(s, "sip:", 4)) 11609 s += 4; 11610 e = strchr(s, '/'); 11611 if (e) 11612 *e = '\0'; 11613 if (option_debug) 11614 ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s); 11615 if (p->owner) 11616 ast_string_field_build(p->owner, call_forward, "SIP/%s", s); 11617 } else { 11618 e = strchr(tmp, '@'); 11619 if (e) { 11620 *e++ = '\0'; 11621 domain = e; 11622 } else { 11623 /* No username part */ 11624 domain = tmp; 11625 } 11626 e = strchr(tmp, '/'); 11627 if (e) 11628 *e = '\0'; 11629 if (!strncasecmp(s, "sip:", 4)) 11630 s += 4; 11631 if (option_debug > 1) 11632 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 11633 if (p->owner) { 11634 pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain); 11635 ast_string_field_set(p->owner, call_forward, s); 11636 } 11637 } 11638 }
| 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 7677 of file chan_sip.c.
References ast_string_field_set, get_header(), get_in_brackets(), and TRUE.
Referenced by handle_request_invite(), handle_request_subscribe(), and handle_response_invite().
07678 { 07679 char contact[BUFSIZ]; 07680 char *c; 07681 07682 /* Look for brackets */ 07683 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 07684 c = get_in_brackets(contact); 07685 07686 /* Save full contact to call pvt for later bye or re-invite */ 07687 ast_string_field_set(pvt, fullcontact, c); 07688 07689 /* Save URI for later ACKs, BYE or RE-invites */ 07690 ast_string_field_set(pvt, okcontacturi, c); 07691 07692 /* We should return false for URI:s we can't handle, 07693 like sips:, tel:, mailto:,ldap: etc */ 07694 return TRUE; 07695 }
| 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 7760 of file chan_sip.c.
References sip_peer::addr, ahp, ast_db_put(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_sched_when(), ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose(), destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, expire_register(), sip_pvt::expiry, sip_peer::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), hp, inaddrcmp(), sip_peer::lastms, LOG_NOTICE, LOG_WARNING, manager_event(), option_verbose, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, sip_pvt::recv, register_peer_exten(), sched, SIP_NAT_ROUTE, SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), SIP_REALTIME, sip_pvt::sipoptions, sip_peer::sipoptions, STANDARD_SIP_PORT, strcasestr(), strsep(), sip_peer::useragent, sip_peer::username, and VERBOSE_PREFIX_3.
Referenced by register_verify().
07761 { 07762 char contact[BUFSIZ]; 07763 char data[BUFSIZ]; 07764 const char *expires = get_header(req, "Expires"); 07765 int expiry = atoi(expires); 07766 char *curi, *n, *pt; 07767 int port; 07768 const char *useragent; 07769 struct hostent *hp; 07770 struct ast_hostent ahp; 07771 struct sockaddr_in oldsin; 07772 07773 ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); 07774 07775 if (ast_strlen_zero(expires)) { /* No expires header */ 07776 expires = strcasestr(contact, ";expires="); 07777 if (expires) { 07778 /* XXX bug here, we overwrite the string */ 07779 expires = strsep((char **) &expires, ";"); /* trim ; and beyond */ 07780 if (sscanf(expires + 9, "%d", &expiry) != 1) 07781 expiry = default_expiry; 07782 } else { 07783 /* Nothing has been specified */ 07784 expiry = default_expiry; 07785 } 07786 } 07787 07788 /* Look for brackets */ 07789 curi = contact; 07790 if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ 07791 strsep(&curi, ";"); /* This is Header options, not URI options */ 07792 curi = get_in_brackets(contact); 07793 07794 /* if they did not specify Contact: or Expires:, they are querying 07795 what we currently have stored as their contact address, so return 07796 it 07797 */ 07798 if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) { 07799 /* If we have an active registration, tell them when the registration is going to expire */ 07800 if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact)) 07801 pvt->expiry = ast_sched_when(sched, peer->expire); 07802 return PARSE_REGISTER_QUERY; 07803 } else if (!strcasecmp(curi, "*") || !expiry) { /* Unregister this peer */ 07804 /* This means remove all registrations and return OK */ 07805 memset(&peer->addr, 0, sizeof(peer->addr)); 07806 if (peer->expire > -1) 07807 ast_sched_del(sched, peer->expire); 07808 peer->expire = -1; 07809 07810 destroy_association(peer); 07811 07812 register_peer_exten(peer, 0); /* Add extension from regexten= setting in sip.conf */ 07813 peer->fullcontact[0] = '\0'; 07814 peer->useragent[0] = '\0'; 07815 peer->sipoptions = 0; 07816 peer->lastms = 0; 07817 07818 if (option_verbose > 2) 07819 ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", peer->name); 07820 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name); 07821 return PARSE_REGISTER_UPDATE; 07822 } 07823 07824 /* Store whatever we got as a contact from the client */ 07825 ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact)); 07826 07827 /* For the 200 OK, we should use the received contact */ 07828 ast_string_field_build(pvt, our_contact, "<%s>", curi); 07829 07830 /* Make sure it's a SIP URL */ 07831 if (strncasecmp(curi, "sip:", 4)) { 07832 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 07833 } else 07834 curi += 4; 07835 /* Ditch q */ 07836 curi = strsep(&curi, ";"); 07837 /* Grab host */ 07838 n = strchr(curi, '@'); 07839 if (!n) { 07840 n = curi; 07841 curi = NULL; 07842 } else 07843 *n++ = '\0'; 07844 pt = strchr(n, ':'); 07845 if (pt) { 07846 *pt++ = '\0'; 07847 port = atoi(pt); 07848 } else 07849 port = STANDARD_SIP_PORT; 07850 oldsin = peer->addr; 07851 if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { 07852 /* XXX This could block for a long time XXX */ 07853 hp = ast_gethostbyname(n, &ahp); 07854 if (!hp) { 07855 ast_log(LOG_WARNING, "Invalid host '%s'\n", n); 07856 return PARSE_REGISTER_FAILED; 07857 } 07858 peer->addr.sin_family = AF_INET; 07859 memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); 07860 peer->addr.sin_port = htons(port); 07861 } else { 07862 /* Don't trust the contact field. Just use what they came to us 07863 with */ 07864 peer->addr = pvt->recv; 07865 } 07866 07867 /* Save SIP options profile */ 07868 peer->sipoptions = pvt->sipoptions; 07869 07870 if (curi) /* Overwrite the default username from config at registration */ 07871 ast_copy_string(peer->username, curi, sizeof(peer->username)); 07872 else 07873 peer->username[0] = '\0'; 07874 07875 if (peer->expire > -1) { 07876 ast_sched_del(sched, peer->expire); 07877 peer->expire = -1; 07878 } 07879 if (expiry > max_expiry) 07880 expiry = max_expiry; 07881 if (expiry < min_expiry) 07882 expiry = min_expiry; 07883 peer->expire = ast_test_flag(&peer->flags[0], SIP_REALTIME) ? -1 : 07884 ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 07885 pvt->expiry = expiry; 07886 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); 07887 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07888 ast_db_put("SIP/Registry", peer->name, data); 07889 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 07890 07891 /* Is this a new IP address for us? */ 07892 if (inaddrcmp(&peer->addr, &oldsin)) { 07893 sip_poke_peer(peer); 07894 if (option_verbose > 2) 07895 ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s port %d expires %d\n", peer->name, ast_inet_ntoa(peer->addr.sin_addr), ntohs(peer->addr.sin_port), expiry); 07896 register_peer_exten(peer, 1); 07897 } 07898 07899 /* Save User agent */ 07900 useragent = get_header(req, "User-Agent"); 07901 if (strcasecmp(useragent, peer->useragent)) { /* XXX copy if they are different ? */ 07902 ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent)); 07903 if (option_verbose > 3) 07904 ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name); 07905 } 07906 return PARSE_REGISTER_UPDATE; 07907 }
| static void parse_request | ( | struct sip_request * | req | ) | [static] |
Parse a SIP message.
Definition at line 4571 of file chan_sip.c.
References ast_log(), ast_strlen_zero(), sip_request::data, determine_firstline_parts(), f, sip_request::header, sip_request::headers, sip_request::line, sip_request::lines, LOG_DEBUG, LOG_WARNING, option_debug, SIP_MAX_HEADERS, SIP_MAX_LINES, and sipdebug.
Referenced by initialize_initreq(), parse_copy(), and sipsock_read().
04572 { 04573 /* Divide fields by NULL's */ 04574 char *c; 04575 int f = 0; 04576 04577 c = req->data; 04578 04579 /* First header starts immediately */ 04580 req->header[f] = c; 04581 while(*c) { 04582 if (*c == '\n') { 04583 /* We've got a new header */ 04584 *c = 0; 04585 04586 if (sipdebug && option_debug > 3) 04587 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04588 if (ast_strlen_zero(req->header[f])) { 04589 /* Line by itself means we're now in content */ 04590 c++; 04591 break; 04592 } 04593 if (f >= SIP_MAX_HEADERS - 1) { 04594 ast_log(LOG_WARNING, "Too many SIP headers. Ignoring.\n"); 04595 } else 04596 f++; 04597 req->header[f] = c + 1; 04598 } else if (*c == '\r') { 04599 /* Ignore but eliminate \r's */ 04600 *c = 0; 04601 } 04602 c++; 04603 } 04604 /* Check for last header */ 04605 if (!ast_strlen_zero(req->header[f])) { 04606 if (sipdebug && option_debug > 3) 04607 ast_log(LOG_DEBUG, "Header %d: %s (%d)\n", f, req->header[f], (int) strlen(req->header[f])); 04608 f++; 04609 } 04610 req->headers = f; 04611 /* Now we process any mime content */ 04612 f = 0; 04613 req->line[f] = c; 04614 while(*c) { 04615 if (*c == '\n') { 04616 /* We've got a new line */ 04617 *c = 0; 04618 if (sipdebug && option_debug > 3) 04619 ast_log(LOG_DEBUG, "Line: %s (%d)\n", req->line[f], (int) strlen(req->line[f])); 04620 if (f >= SIP_MAX_LINES - 1) { 04621 ast_log(LOG_WARNING, "Too many SDP lines. Ignoring.\n"); 04622 } else 04623 f++; 04624 req->line[f] = c + 1; 04625 } else if (*c == '\r') { 04626 /* Ignore and eliminate \r's */ 04627 *c = 0; 04628 } 04629 c++; 04630 } 04631 /* Check for last line */ 04632 if (!ast_strlen_zero(req->line[f])) 04633 f++; 04634 req->lines = f; 04635 if (*c) 04636 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 04637 /* Split up the first line parts */ 04638 determine_firstline_parts(req); 04639 }
| static unsigned int parse_sip_options | ( | struct sip_pvt * | pvt, | |
| const char * | supported | |||
| ) | [static] |
Parse supported header in incoming packet.
Definition at line 1669 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), FALSE, LOG_DEBUG, ast_udptl_protocol::next, option_debug, sip_options, sipdebug, sip_pvt::sipoptions, text, and TRUE.
Referenced by handle_request_invite().
01670 { 01671 char *next, *sep; 01672 char *temp; 01673 unsigned int profile = 0; 01674 int i, found; 01675 01676 if (ast_strlen_zero(supported) ) 01677 return 0; 01678 temp = ast_strdupa(supported); 01679 01680 if (option_debug > 2 && sipdebug) 01681 ast_log(LOG_DEBUG, "Begin: parsing SIP \"Supported: %s\"\n", supported); 01682 01683 for (next = temp; next; next = sep) { 01684 found = FALSE; 01685 if ( (sep = strchr(next, ',')) != NULL) 01686 *sep++ = '\0'; 01687 next = ast_skip_blanks(next); 01688 if (option_debug > 2 && sipdebug) 01689 ast_log(LOG_DEBUG, "Found SIP option: -%s-\n", next); 01690 for (i=0; i < (sizeof(sip_options) / sizeof(sip_options[0])); i++) { 01691 if (!strcasecmp(next, sip_options[i].text)) { 01692 profile |= sip_options[i].id; 01693 found = TRUE; 01694 if (option_debug > 2 && sipdebug) 01695 ast_log(LOG_DEBUG, "Matched SIP option: %s\n", next); 01696 break; 01697 } 01698 } 01699 if (!found && option_debug > 2 && sipdebug) { 01700 if (!strncasecmp(next, "x-", 2)) 01701 ast_log(LOG_DEBUG, "Found private SIP option, not supported: %s\n", next); 01702 else 01703 ast_log(LOG_DEBUG, "Found no match for SIP option: %s (Please file bug report!)\n", next); 01704 } 01705 } 01706 01707 if (pvt) 01708 pvt->sipoptions = profile; 01709 return profile; 01710 }
| static int peer_status | ( | struct sip_peer * | peer, | |
| char * | status, | |||
| int | statuslen | |||
| ) | [static] |
Report Peer status in character string.
Definition at line 9442 of file chan_sip.c.
References sip_peer::lastms, and sip_peer::maxms.
09443 { 09444 int res = 0; 09445 if (peer->maxms) { 09446 if (peer->lastms < 0) { 09447 ast_copy_string(status, "UNREACHABLE", statuslen); 09448 } else if (peer->lastms > peer->maxms) { 09449 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 09450 res = 1; 09451 } else if (peer->lastms) { 09452 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 09453 res = 1; 09454 } else { 09455 ast_copy_string(status, "UNKNOWN", statuslen); 09456 } 09457 } else { 09458 ast_copy_string(status, "Unmonitored", statuslen); 09459 /* Checking if port is 0 */ 09460 res = -1; 09461 } 09462 return res; 09463 }
| 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 9910 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().
09911 { 09912 int x, codec; 09913 09914 for(x = 0; x < 32 ; x++) { 09915 codec = ast_codec_pref_index(pref, x); 09916 if (!codec) 09917 break; 09918 ast_cli(fd, "%s", ast_getformatname(codec)); 09919 ast_cli(fd, ":%d", pref->framing[x]); 09920 if (x < 31 && ast_codec_pref_index(pref, x + 1)) 09921 ast_cli(fd, ","); 09922 } 09923 if (!x) 09924 ast_cli(fd, "none"); 09925 }
| static void print_group | ( | int | fd, | |
| ast_group_t | group, | |||
| int | crlf | |||
| ) | [static] |
Print call group and pickup group.
Definition at line 9701 of file chan_sip.c.
References ast_cli(), and ast_print_group().
Referenced by _sip_show_peer(), and sip_show_user().
09702 { 09703 char buf[256]; 09704 ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) ); 09705 }
| 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 4720 of file chan_sip.c.
References append_history, ast_clear_flag, ast_codec_choose(), ast_codec_pref_setsize(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_FORMAT_AUDIO_MASK, ast_getformatname_multiple(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_control_data(), ast_queue_frame(), ast_rtp_alloc_size(), ast_rtp_codec_getformat(), ast_rtp_codec_getpref(), ast_rtp_codec_setpref(), AST_RTP_DTMF, ast_rtp_get_current_formats(), ast_rtp_lookup_mime_multiple(), ast_rtp_new_init(), AST_RTP_OPT_G726_NONSTANDARD, ast_rtp_pt_clear(), ast_rtp_pt_copy(), ast_rtp_set_m_type(), ast_rtp_set_peer(), ast_rtp_set_rtpmap_type(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_stop(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_local_max_datagram(), ast_udptl_set_peer(), ast_udptl_stop(), ast_verbose(), sip_pvt::autoframing, sip_pvt::capability, t38properties::capability, sip_request::data, debug, EVENT_FLAG_CALL, FALSE, sip_pvt::flags, format, get_sdp(), get_sdp_iterate(), hp, sip_pvt::jointcapability, t38properties::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastinvite, sip_pvt::lastrtprx, sip_pvt::lastrtptx, len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, LONG_MAX, LONG_MIN, manager_event(), ast_channel::nativeformats, sip_pvt::noncodeccapability, option_debug, sip_pvt::owner, sip_pvt::peercapability, t38properties::peercapability, portno, sip_pvt::prefs, ast_channel::readformat, sip_pvt::rtp, s, S_OR, sip_request::sdp_start, sip_debug_test_pvt(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_G726_NONSTANDARD, SIP_NOVIDEO, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, SIP_PAGE2_RFC2833_COMPENSATE, sip_peer_hold(), t38properties::state, sip_pvt::t38, T38_DISABLED, T38_PEER_DIRECT, T38_PEER_REINVITE, T38FAX_FILL_BIT_REMOVAL, T38FAX_RATE_12000, T38FAX_RATE_14400, T38FAX_RATE_2400, T38FAX_RATE_4800, T38FAX_RATE_7200, T38FAX_RATE_9600, T38FAX_RATE_MANAGEMENT_LOCAL_TCF, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_TRANSCODING_JBIG, T38FAX_TRANSCODING_MMR, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, T38FAX_VERSION_0, T38FAX_VERSION_1, TRUE, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, sip_pvt::vrtp, and ast_channel::writeformat.
04721 { 04722 const char *m; /* SDP media offer */ 04723 const char *c; 04724 const char *a; 04725 char host[258]; 04726 int len = -1; 04727 int portno = -1; /*!< RTP Audio port number */ 04728 int vportno = -1; /*!< RTP Video port number */ 04729 int udptlportno = -1; 04730 int peert38capability = 0; 04731 char s[256]; 04732 int old = 0; 04733 04734 /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 04735 int peercapability = 0, peernoncodeccapability = 0; 04736 int vpeercapability = 0, vpeernoncodeccapability = 0; 04737 struct sockaddr_in sin; /*!< media socket address */ 04738 struct sockaddr_in vsin; /*!< Video socket address */ 04739 04740 const char *codecs; 04741 struct hostent *hp; /*!< RTP Audio host IP */ 04742 struct hostent *vhp = NULL; /*!< RTP video host IP */ 04743 struct ast_hostent audiohp; 04744 struct ast_hostent videohp; 04745 int codec; 04746 int destiterator = 0; 04747 int iterator; 04748 int sendonly = -1; 04749 int numberofports; 04750 struct ast_rtp *newaudiortp, *newvideortp; /* Buffers for codec handling */ 04751 int newjointcapability; /* Negotiated capability */ 04752 int newpeercapability; 04753 int newnoncodeccapability; 04754 int numberofmediastreams = 0; 04755 int debug = sip_debug_test_pvt(p); 04756 04757 int found_rtpmap_codecs[32]; 04758 int last_rtpmap_codec=0; 04759 04760 if (!p->rtp) { 04761 ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n"); 04762 return -1; 04763 } 04764 04765 /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */ 04766 newaudiortp = alloca(ast_rtp_alloc_size()); 04767 memset(newaudiortp, 0, ast_rtp_alloc_size()); 04768 ast_rtp_new_init(newaudiortp); 04769 ast_rtp_pt_clear(newaudiortp); 04770 04771 newvideortp = alloca(ast_rtp_alloc_size()); 04772 memset(newvideortp, 0, ast_rtp_alloc_size()); 04773 ast_rtp_new_init(newvideortp); 04774 ast_rtp_pt_clear(newvideortp); 04775 04776 /* Update our last rtprx when we receive an SDP, too */ 04777 p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */ 04778 04779 04780 /* Try to find first media stream */ 04781 m = get_sdp(req, "m"); 04782 destiterator = req->sdp_start; 04783 c = get_sdp_iterate(&destiterator, req, "c"); 04784 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 04785 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 04786 return -1; 04787 } 04788 04789 /* Check for IPv4 address (not IPv6 yet) */ 04790 if (sscanf(c, "IN IP4 %256s", host) != 1) { 04791 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 04792 return -1; 04793 } 04794 04795 /* XXX This could block for a long time, and block the main thread! XXX */ 04796 hp = ast_gethostbyname(host, &audiohp); 04797 if (!hp) { 04798 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 04799 return -1; 04800 } 04801 vhp = hp; /* Copy to video address as default too */ 04802 04803 iterator = req->sdp_start; 04804 ast_set_flag(&p->flags[0], SIP_NOVIDEO); 04805 04806 04807 /* Find media streams in this SDP offer */ 04808 while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { 04809 int x; 04810 int audio = FALSE; 04811 04812 numberofports = 1; 04813 if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 04814 (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) { 04815 audio = TRUE; 04816 numberofmediastreams++; 04817 /* Found audio stream in this media definition */ 04818 portno = x; 04819 /* Scan through the RTP payload types specified in a "m=" line: */ 04820 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 04821 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 04822 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 04823 return -1; 04824 } 04825 if (debug) 04826 ast_verbose("Found RTP audio format %d\n", codec); 04827 ast_rtp_set_m_type(newaudiortp, codec); 04828 } 04829 } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) || 04830 (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) { 04831 /* If it is not audio - is it video ? */ 04832 ast_clear_flag(&p->flags[0], SIP_NOVIDEO); 04833 numberofmediastreams++; 04834 vportno = x; 04835 /* Scan through the RTP payload types specified in a "m=" line: */ 04836 for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) { 04837 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 04838 ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs); 04839 return -1; 04840 } 04841 if (debug) 04842 ast_verbose("Found RTP video format %d\n", codec); 04843 ast_rtp_set_m_type(newvideortp, codec); 04844 } 04845 } else if (p->udptl && ( (sscanf(m, "image %d udptl t38%n", &x, &len) == 1) || 04846 (sscanf(m, "image %d UDPTL t38%n", &x, &len) == 1) )) { 04847 if (debug) 04848 ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); 04849 udptlportno = x; 04850 numberofmediastreams++; 04851 04852 if (p->owner && p->lastinvite) { 04853 p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ 04854 if (option_debug > 1) 04855 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); 04856 } else { 04857 p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ 04858 if (option_debug > 1) 04859 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 04860 } 04861 } else 04862 ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); 04863 if (numberofports > 1) 04864 ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports); 04865 04866 04867 /* Check for Media-description-level-address for audio */ 04868 c = get_sdp_iterate(&destiterator, req, "c"); 04869 if (!ast_strlen_zero(c)) { 04870 if (sscanf(c, "IN IP4 %256s", host) != 1) { 04871 ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c); 04872 } else { 04873 /* XXX This could block for a long time, and block the main thread! XXX */ 04874 if (audio) { 04875 if ( !(hp = ast_gethostbyname(host, &audiohp))) { 04876 ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c); 04877 return -2; 04878 } 04879 } else if (!(vhp = ast_gethostbyname(host, &videohp))) { 04880 ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c); 04881 return -2; 04882 } 04883 } 04884 04885 } 04886 } 04887 if (portno == -1 && vportno == -1 && udptlportno == -1) 04888 /* No acceptable offer found in SDP - we have no ports */ 04889 /* Do not change RTP or VRTP if this is a re-invite */ 04890 return -2; 04891 04892 if (numberofmediastreams > 2) 04893 /* We have too many fax, audio and/or video media streams, fail this offer */ 04894 return -3; 04895 04896 /* RTP addresses and ports for audio and video */ 04897 sin.sin_family = AF_INET; 04898 vsin.sin_family = AF_INET; 04899 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 04900 if (vhp) 04901 memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr)); 04902 04903 /* Setup UDPTL port number */ 04904 if (p->udptl) { 04905 if (udptlportno > 0) { 04906 sin.sin_port = htons(udptlportno); 04907 ast_udptl_set_peer(p->udptl, &sin); 04908 if (debug) 04909 ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 04910 } else { 04911 ast_udptl_stop(p->udptl); 04912 if (debug) 04913 ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n"); 04914 } 04915 } 04916 04917 04918 if (p->rtp) { 04919 if (portno > 0) { 04920 sin.sin_port = htons(portno); 04921 ast_rtp_set_peer(p->rtp, &sin); 04922 if (debug) 04923 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 04924 } else { 04925 if (udptlportno > 0) { 04926 if (debug) 04927 ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session. Callid %s\n", p->callid); 04928 } else { 04929 ast_rtp_stop(p->rtp); 04930 if (debug) 04931 ast_verbose("Peer doesn't provide audio. Callid %s\n", p->callid); 04932 } 04933 } 04934 } 04935 /* Setup video port number */ 04936 if (vportno != -1) 04937 vsin.sin_port = htons(vportno); 04938 04939 /* Next, scan through each "a=rtpmap:" line, noting each 04940 * specified RTP payload type (with corresponding MIME subtype): 04941 */ 04942 /* XXX This needs to be done per media stream, since it's media stream specific */ 04943 iterator = req->sdp_start; 04944 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 04945 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 04946 if (option_debug > 1) { 04947 int breakout = FALSE; 04948 04949 /* If we're debugging, check for unsupported sdp options */ 04950 if (!strncasecmp(a, "rtcp:", (size_t) 5)) { 04951 if (debug) 04952 ast_verbose("Got unsupported a:rtcp in SDP offer \n"); 04953 breakout = TRUE; 04954 } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) { 04955 /* Format parameters: Not supported */ 04956 /* Note: This is used for codec parameters, like bitrate for 04957 G722 and video formats for H263 and H264 04958 See RFC2327 for an example */ 04959 if (debug) 04960 ast_verbose("Got unsupported a:fmtp in SDP offer \n"); 04961 breakout = TRUE; 04962 } else if (!strncasecmp(a, "framerate:", (size_t) 10)) { 04963 /* Video stuff: Not supported */ 04964 if (debug) 04965 ast_verbose("Got unsupported a:framerate in SDP offer \n"); 04966 breakout = TRUE; 04967 } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) { 04968 /* Video stuff: Not supported */ 04969 if (debug) 04970 ast_verbose("Got unsupported a:maxprate in SDP offer \n"); 04971 breakout = TRUE; 04972 } else if (!strncasecmp(a, "crypto:", (size_t) 7)) { 04973 /* SRTP stuff, not yet supported */ 04974 if (debug) 04975 ast_verbose("Got unsupported a:crypto in SDP offer \n"); 04976 breakout = TRUE; 04977 } 04978 if (breakout) /* We have a match, skip to next header */ 04979 continue; 04980 } 04981 if (!strcasecmp(a, "sendonly")) { 04982 if (sendonly == -1) 04983 sendonly = 1; 04984 continue; 04985 } else if (!strcasecmp(a, "inactive")) { 04986 if (sendonly == -1) 04987 sendonly = 2; 04988 continue; 04989 } else if (!strcasecmp(a, "sendrecv")) { 04990 if (sendonly == -1) 04991 sendonly = 0; 04992 continue; 04993 } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) { 04994 char *tmp = strrchr(a, ':'); 04995 long int framing = 0; 04996 if (tmp) { 04997 tmp++; 04998 framing = strtol(tmp, NULL, 10); 04999 if (framing == LONG_MIN || framing == LONG_MAX) { 05000 framing = 0; 05001 if (option_debug) 05002 ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a); 05003 } 05004 } 05005 if (framing && last_rtpmap_codec) { 05006 if (p->autoframing) { 05007 struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp); 05008 int codec_n; 05009 int format = 0; 05010 for (codec_n = 0; codec_n < last_rtpmap_codec; codec_n++) { 05011 format = ast_rtp_codec_getformat(found_rtpmap_codecs[codec_n]); 05012 if (!format) /* non-codec or not found */ 05013 continue; 05014 if (option_debug) 05015 ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing); 05016 ast_codec_pref_setsize(pref, format, framing); 05017 } 05018 ast_rtp_codec_setpref(p->rtp, pref); 05019 } 05020 } 05021 memset(&found_rtpmap_codecs, 0, sizeof(found_rtpmap_codecs)); 05022 last_rtpmap_codec = 0; 05023 continue; 05024 } else if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) == 2) { 05025 /* We have a rtpmap to handle */ 05026 if (debug) 05027 ast_verbose("Found description format %s for ID %d\n", mimeSubtype, codec); 05028 found_rtpmap_codecs[last_rtpmap_codec] = codec; 05029 last_rtpmap_codec++; 05030 05031 /* Note: should really look at the 'freq' and '#chans' params too */ 05032 ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, 05033 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0); 05034 if (p->vrtp) 05035 ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0); 05036 } 05037 } 05038 05039 if (udptlportno != -1) { 05040 int found = 0, x; 05041 05042 old = 0; 05043 05044 /* Scan trough the a= lines for T38 attributes and set apropriate fileds */ 05045 iterator = req->sdp_start; 05046 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 05047 if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) { 05048 found = 1; 05049 if (option_debug > 2) 05050 ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x); 05051 } else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1)) { 05052 found = 1; 05053 if (option_debug > 2) 05054 ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x); 05055 switch (x) { 05056 case 14400: 05057 peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05058 break; 05059 case 12000: 05060 peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05061 break; 05062 case 9600: 05063 peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05064 break; 05065 case 7200: 05066 peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400; 05067 break; 05068 case 4800: 05069 peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400; 05070 break; 05071 case 2400: 05072 peert38capability |= T38FAX_RATE_2400; 05073 break; 05074 } 05075 } else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) { 05076 found = 1; 05077 if (option_debug > 2) 05078 ast_log(LOG_DEBUG, "FaxVersion: %d\n",x); 05079 if (x == 0) 05080 peert38capability |= T38FAX_VERSION_0; 05081 else if (x == 1) 05082 peert38capability |= T38FAX_VERSION_1; 05083 } else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1)) { 05084 found = 1; 05085 if (option_debug > 2) 05086 ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x); 05087 ast_udptl_set_far_max_datagram(p->udptl, x); 05088 ast_udptl_set_local_max_datagram(p->udptl, x); 05089 } else if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) { 05090 found = 1; 05091 if (option_debug > 2) 05092 ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x); 05093 if (x == 1) 05094 peert38capability |= T38FAX_FILL_BIT_REMOVAL; 05095 } else if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) { 05096 found = 1; 05097 if (option_debug > 2) 05098 ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x); 05099 if (x == 1) 05100 peert38capability |= T38FAX_TRANSCODING_MMR; 05101 } 05102 if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) { 05103 found = 1; 05104 if (option_debug > 2) 05105 ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x); 05106 if (x == 1) 05107 peert38capability |= T38FAX_TRANSCODING_JBIG; 05108 } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) { 05109 found = 1; 05110 if (option_debug > 2) 05111 ast_log(LOG_DEBUG, "RateManagement: %s\n", s); 05112 if (!strcasecmp(s, "localTCF")) 05113 peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF; 05114 else if (!strcasecmp(s, "transferredTCF")) 05115 peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 05116 } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) { 05117 found = 1; 05118 if (option_debug > 2) 05119 ast_log(LOG_DEBUG, "UDP EC: %s\n", s); 05120 if (!strcasecmp(s, "t38UDPRedundancy")) { 05121 peert38capability |= T38FAX_UDP_EC_REDUNDANCY; 05122 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY); 05123 } else if (!strcasecmp(s, "t38UDPFEC")) { 05124 peert38capability |= T38FAX_UDP_EC_FEC; 05125 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC); 05126 } else { 05127 peert38capability |= T38FAX_UDP_EC_NONE; 05128 ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE); 05129 } 05130 } 05131 } 05132 if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 05133 p->t38.peercapability = peert38capability; 05134 p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */ 05135 peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); 05136 p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */ 05137 } 05138 if (debug) 05139 ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n", 05140 p->t38.capability, 05141 p->t38.peercapability, 05142 p->t38.jointcapability); 05143 } else { 05144 p->t38.state = T38_DISABLED; 05145 if (option_debug > 2) 05146 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 05147 } 05148 05149 /* Now gather all of the codecs that we are asked for: */ 05150 ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); 05151 ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); 05152 05153 newjointcapability = p->capability & (peercapability | vpeercapability); 05154 newpeercapability = (peercapability | vpeercapability); 05155 newnoncodeccapability = p->noncodeccapability & peernoncodeccapability; 05156 05157 05158 if (debug) { 05159 /* shame on whoever coded this.... */ 05160 char s1[BUFSIZ], s2[BUFSIZ], s3[BUFSIZ], s4[BUFSIZ]; 05161 05162 ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n", 05163 ast_getformatname_multiple(s1, BUFSIZ, p->capability), 05164 ast_getformatname_multiple(s2, BUFSIZ, newpeercapability), 05165 ast_getformatname_multiple(s3, BUFSIZ, vpeercapability), 05166 ast_getformatname_multiple(s4, BUFSIZ, newjointcapability)); 05167 05168 ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n", 05169 ast_rtp_lookup_mime_multiple(s1, BUFSIZ, p->noncodeccapability, 0, 0), 05170 ast_rtp_lookup_mime_multiple(s2, BUFSIZ, peernoncodeccapability, 0, 0), 05171 ast_rtp_lookup_mime_multiple(s3, BUFSIZ, newnoncodeccapability, 0, 0)); 05172 } 05173 if (!newjointcapability) { 05174 /* If T.38 was not negotiated either, totally bail out... */ 05175 if (!p->t38.jointcapability) { 05176 ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n"); 05177 /* Do NOT Change current setting */ 05178 return -1; 05179 } else { 05180 if (option_debug > 2) 05181 ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n"); 05182 return 0; 05183 } 05184 } 05185 05186 /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since 05187 they are acceptable */ 05188 p->jointcapability = newjointcapability; /* Our joint codec profile for this call */ 05189 p->peercapability = newpeercapability; /* The other sides capability in latest offer */ 05190 p->jointnoncodeccapability = newnoncodeccapability; /* DTMF capabilities */ 05191 05192 ast_rtp_pt_copy(p->rtp, newaudiortp); 05193 if (p->vrtp) 05194 ast_rtp_pt_copy(p->vrtp, newvideortp); 05195 05196 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) { 05197 ast_clear_flag(&p->flags[0], SIP_DTMF); 05198 if (newnoncodeccapability & AST_RTP_DTMF) { 05199 /* XXX Would it be reasonable to drop the DSP at this point? XXX */ 05200 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 05201 /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */ 05202 ast_rtp_setdtmf(p->rtp, 1); 05203 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 05204 } else { 05205 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 05206 } 05207 } 05208 05209 /* Setup audio port number */ 05210 if (p->rtp && sin.sin_port) { 05211 ast_rtp_set_peer(p->rtp, &sin); 05212 if (debug) 05213 ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 05214 } 05215 05216 /* Setup video port number */ 05217 if (p->vrtp && vsin.sin_port) { 05218 ast_rtp_set_peer(p->vrtp, &vsin); 05219 if (debug) 05220 ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port)); 05221 } 05222 05223 /* Ok, we're going with this offer */ 05224 if (option_debug > 1) { 05225 char buf[BUFSIZ]; 05226 ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, BUFSIZ, p->jointcapability)); 05227 } 05228 05229 if (!p->owner) /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */ 05230 return 0; 05231 05232 if (option_debug > 3) 05233 ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n"); 05234 05235 if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 05236 if (debug) { 05237 char s1[BUFSIZ], s2[BUFSIZ]; 05238 ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 05239 ast_getformatname_multiple(s1, BUFSIZ, p->jointcapability), 05240 ast_getformatname_multiple(s2, BUFSIZ, p->owner->nativeformats)); 05241 } 05242 p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability); 05243 ast_set_read_format(p->owner, p->owner->readformat); 05244 ast_set_write_format(p->owner, p->owner->writeformat); 05245 } 05246 05247 if (sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 05248 ast_queue_control(p->owner, AST_CONTROL_UNHOLD); 05249 /* Activate a re-invite */ 05250 ast_queue_frame(p->owner, &ast_null_frame); 05251 } else if (!sin.sin_addr.s_addr || sendonly) { 05252 ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 05253 S_OR(p->mohsuggest, NULL), 05254 !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); 05255 if (sendonly) 05256 ast_rtp_stop(p->rtp); 05257 /* RTCP needs to go ahead, even if we're on hold!!! */ 05258 /* Activate a re-invite */ 05259 ast_queue_frame(p->owner, &ast_null_frame); 05260 } 05261 05262 /* Manager Hold and Unhold events must be generated, if necessary */ 05263 if (sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) { 05264 if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 05265 append_history(p, "Unhold", "%s", req->data); 05266 if (global_callevents) 05267 manager_event(EVENT_FLAG_CALL, "Unhold", 05268 "Channel: %s\r\n" 05269 "Uniqueid: %s\r\n", 05270 p->owner->name, 05271 p->owner->uniqueid); 05272 if (global_notifyhold) 05273 sip_peer_hold(p, 0); 05274 } 05275 ast_clear_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ 05276 } else if (!sin.sin_addr.s_addr || sendonly ) { 05277 /* No address for RTP, we're on hold */ 05278 append_history(p, "Hold", "%s", req->data); 05279 05280 if (global_callevents && !ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) { 05281 manager_event(EVENT_FLAG_CALL, "Hold", 05282 "Channel: %s\r\n" 05283 "Uniqueid: %s\r\n", 05284 p->owner->name, 05285 p->owner->uniqueid); 05286 } 05287 if (sendonly == 1) /* One directional hold (sendonly/recvonly) */ 05288 ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR); 05289 else if (sendonly == 2) /* Inactive stream */ 05290 ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE); 05291 if (global_notifyhold) 05292 sip_peer_hold(p, 1); 05293 } 05294 05295 return 0; 05296 }
| static struct sip_peer * realtime_peer | ( | const char * | newpeername, | |
| struct sockaddr_in * | sin | |||
| ) | [static] |
realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
Definition at line 2407 of file chan_sip.c.
References ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), ipaddr, ast_variable::name, ast_variable::next, ast_variable::value, and var.
02408 { 02409 struct sip_peer *peer; 02410 struct ast_variable *var = NULL; 02411 struct ast_variable *tmp; 02412 char ipaddr[INET_ADDRSTRLEN]; 02413 02414 /* First check on peer name */ 02415 if (newpeername) 02416 var = ast_load_realtime("sippeers", "name", newpeername, NULL); 02417 else if (sin) { /* Then check on IP address for dynamic peers */ 02418 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 02419 var = ast_load_realtime("sippeers", "host", ipaddr, NULL); /* First check for fixed IP hosts */ 02420 if (!var) 02421 var = ast_load_realtime("sippeers", "ipaddr", ipaddr, NULL); /* Then check for registred hosts */ 02422 } 02423 02424 if (!var) 02425 return NULL; 02426 02427 for (tmp = var; tmp; tmp = tmp->next) { 02428 /* If this is type=user, then skip this object. */ 02429 if (!strcasecmp(tmp->name, "type") && 02430 !strcasecmp(tmp->value, "user")) { 02431 ast_variables_destroy(var); 02432 return NULL; 02433 } else if (!newpeername && !strcasecmp(tmp->name, "name")) { 02434 newpeername = tmp->value; 02435 } 02436 } 02437 02438 if (!newpeername) { /* Did not find peer in realtime */ 02439 ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", ipaddr); 02440 ast_variables_destroy(var); 02441 return NULL; 02442 } 02443 02444 /* Peer found in realtime, now build it in memory */ 02445 peer = build_peer(newpeername, var, NULL, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02446 if (!peer) { 02447 ast_variables_destroy(var); 02448 return NULL; 02449 } 02450 02451 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02452 /* Cache peer */ 02453 ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); 02454 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) { 02455 if (peer->expire > -1) { 02456 ast_sched_del(sched, peer->expire); 02457 } 02458 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_register, (void *)peer); 02459 } 02460 ASTOBJ_CONTAINER_LINK(&peerl,peer); 02461 } else { 02462 ast_set_flag(&peer->flags[0], SIP_REALTIME); 02463 } 02464 ast_variables_destroy(var); 02465 02466 return peer; 02467 }
| 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 2292 of file chan_sip.c.
References ast_config_AST_SYSTEM_NAME, ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, ast_update_realtime(), global_flags, ipaddr, and SIP_PAGE2_RTSAVE_SYSNAME.
02293 { 02294 char port[10]; 02295 char ipaddr[INET_ADDRSTRLEN]; 02296 char regseconds[20]; 02297 02298 char *sysname = ast_config_AST_SYSTEM_NAME; 02299 char *syslabel = NULL; 02300 02301 time_t nowtime = time(NULL) + expirey; 02302 const char *fc = fullcontact ? "fullcontact" : NULL; 02303 02304 snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime); /* Expiration time */ 02305 ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr)); 02306 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 02307 02308 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 02309 sysname = NULL; 02310 else if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME)) 02311 syslabel = "regserver"; 02312 02313 if (fc) 02314 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02315 "port", port, "regseconds", regseconds, 02316 "username", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */ 02317 else 02318 ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, 02319 "port", port, "regseconds", regseconds, 02320 "username", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */ 02321 }
| 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 2517 of file chan_sip.c.
References ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, ast_variable::value, and var.
02518 { 02519 struct ast_variable *var; 02520 struct ast_variable *tmp; 02521 struct sip_user *user = NULL; 02522 02523 var = ast_load_realtime("sipusers", "name", username, NULL); 02524 02525 if (!var) 02526 return NULL; 02527 02528 for (tmp = var; tmp; tmp = tmp->next) { 02529 if (!strcasecmp(tmp->name, "type") && 02530 !strcasecmp(tmp->value, "peer")) { 02531 ast_variables_destroy(var); 02532 return NULL; 02533 } 02534 } 02535 02536 user = build_user(username, var, !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)); 02537 02538 if (!user) { /* No user found */ 02539 ast_variables_destroy(var); 02540 return NULL; 02541 } 02542 02543 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 02544 ast_set_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02545 suserobjs++; 02546 ASTOBJ_CONTAINER_LINK(&userl,user); 02547 } else { 02548 /* Move counter from s to r... */ 02549 suserobjs--; 02550 ruserobjs++; 02551 ast_set_flag(&user->flags[0], SIP_REALTIME); 02552 } 02553 ast_variables_destroy(var); 02554 return user; 02555 }
| static void receive_message | ( | struct sip_pvt * | p, | |
| struct sip_request * | req | |||
| ) | [static] |
Receive SIP MESSAGE method messages.
Definition at line 9327 of file chan_sip.c.
References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose(), DEFAULT_TRANS_TIMEOUT, f, get_header(), get_msg_text(), LOG_WARNING, sip_pvt::owner, sip_debug_test_pvt(), sip_scheddestroy(), and transmit_response().
Referenced by handle_request_message().
09328 { 09329 char buf[1024]; 09330 struct ast_frame f; 09331 const char *content_type = get_header(req, "Content-Type"); 09332 09333 if (strcmp(content_type, "text/plain")) { /* No text/plain attachment */ 09334 transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */ 09335 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09336 return; 09337 } 09338 09339 if (get_msg_text(buf, sizeof(buf), req)) { 09340 ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); 09341 transmit_response(p, "202 Accepted", req); 09342 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09343 return; 09344 } 09345 09346 if (p->owner) { 09347 if (sip_debug_test_pvt(p)) 09348 ast_verbose("Message received: '%s'\n", buf); 09349 memset(&f, 0, sizeof(f)); 09350 f.frametype = AST_FRAME_TEXT; 09351 f.subclass = 0; 09352 f.offset = 0; 09353 f.data = buf; 09354 f.datalen = strlen(buf); 09355 ast_queue_frame(p->owner, &f); 09356 transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */ 09357 } else { /* Message outside of a call, we do not support that */ 09358 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); 09359 transmit_response(p, "405 Method Not Allowed", req); /* Good enough, or? */ 09360 } 09361 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 09362 return; 09363 }
| static char * referstatus2str | ( | enum referstatus | rstatus | ) | [static] |
Convert transfer status to string.
Definition at line 1604 of file chan_sip.c.
References referstatusstrings, and text.
Referenced by __sip_show_channels().
01605 { 01606 int i = (sizeof(referstatusstrings) / sizeof(referstatusstrings[0])); 01607 int x; 01608 01609 for (x = 0; x < i; x++) { 01610 if (referstatusstrings[x].status == rstatus) 01611 return (char *) referstatusstrings[x].text; 01612 } 01613 return ""; 01614 }
| static void reg_source_db | ( | struct sip_peer * | peer | ) | [static] |
Get registration details from Asterisk DB.
Definition at line 7617 of file chan_sip.c.
References sip_peer::addr, ast_db_get(), ast_inet_ntoa(), ast_log(), ast_random(), ast_sched_add(), ast_sched_del(), ast_test_flag, sip_peer::expire, expire_register(), sip_peer::flags, sip_peer::fullcontact, LOG_DEBUG, option_debug, sip_peer::pokeexpire, register_peer_exten(), sched, SIP_PAGE2_RT_FROMCONTACT, sip_poke_peer(), sip_poke_peer_s(), sipsock, strsep(), TRUE, sip_peer::username, and username.
07618 { 07619 char data[256]; 07620 struct in_addr in; 07621 int expiry; 07622 int port; 07623 char *scan, *addr, *port_str, *expiry_str, *username, *contact; 07624 07625 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT)) 07626 return; 07627 if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data))) 07628 return; 07629 07630 scan = data; 07631 addr = strsep(&scan, ":"); 07632 port_str = strsep(&scan, ":"); 07633 expiry_str = strsep(&scan, ":"); 07634 username = strsep(&scan, ":"); 07635 contact = scan; /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */ 07636 07637 if (!inet_aton(addr, &in)) 07638 return; 07639 07640 if (port_str) 07641 port = atoi(port_str); 07642 else 07643 return; 07644 07645 if (expiry_str) 07646 expiry = atoi(expiry_str); 07647 else 07648 return; 07649 07650 if (username) 07651 ast_copy_string(peer->username, username, sizeof(peer->username)); 07652 if (contact) 07653 ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact)); 07654 07655 if (option_debug > 1) 07656 ast_log(LOG_DEBUG, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n", 07657 peer->name, peer->username, ast_inet_ntoa(in), port, expiry); 07658 07659 memset(&peer->addr, 0, sizeof(peer->addr)); 07660 peer->addr.sin_family = AF_INET; 07661 peer->addr.sin_addr = in; 07662 peer->addr.sin_port = htons(port); 07663 if (sipsock < 0) { 07664 /* SIP isn't up yet, so schedule a poke only, pretty soon */ 07665 if (peer->pokeexpire > -1) 07666 ast_sched_del(sched, peer->pokeexpire); 07667 peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer); 07668 } else 07669 sip_poke_peer(peer); 07670 if (peer->expire > -1) 07671 ast_sched_del(sched, peer->expire); 07672 peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer); 07673 register_peer_exten(peer, TRUE); 07674 }
| static void register_peer_exten | ( | struct sip_peer * | peer, | |
| int | onoff | |||
| ) | [static] |
Automatically add peer extension to dial plan.
Definition at line 2324 of file chan_sip.c.
References ast_add_extension(), ast_context_find(), ast_context_remove_extension(), ast_free, ast_log(), ast_strdup, ast_strlen_zero(), domain::context, ext, LOG_WARNING, sip_peer::regexten, S_OR, and strsep().
02325 { 02326 char multi[256]; 02327 char *stringp, *ext, *context; 02328 02329 /* XXX note that global_regcontext is both a global 'enable' flag and 02330 * the name of the global regexten context, if not specified 02331 * individually. 02332 */ 02333 if (ast_strlen_zero(global_regcontext)) 02334 return; 02335 02336 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 02337 stringp = multi; 02338 while ((ext = strsep(&stringp, "&"))) { 02339 if ((context = strchr(ext, '@'))) { 02340 *context++ = '\0'; /* split ext@context */ 02341 if (!ast_context_find(context)) { 02342 ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context); 02343 continue; 02344 } 02345 } else { 02346 context = global_regcontext; 02347 } 02348 if (onoff) 02349 ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop", 02350 ast_strdup(peer->name), ast_free, "SIP"); 02351 else 02352 ast_context_remove_extension(context, ext, 1, NULL); 02353 } 02354 }
| 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 8266 of file chan_sip.c.
References ast_apply_ha(), ast_copy_flags, ast_device_state_changed(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_rtp_codec_setpref(), ast_string_field_set, ast_test_flag, ast_uri_decode(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, AUTH_NOT_FOUND, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, sip_peer::autoframing, sip_pvt::autoframing, build_contact(), check_auth(), check_sip_domain(), EVENT_FLAG_SYSTEM, exten, find_peer(), sip_pvt::flags, sip_peer::flags, get_header(), get_in_brackets(), sip_peer::ha, sip_pvt::initreq, sip_peer::lastmsgssent, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event(), sip_peer::md5secret, name, option_debug, parse_register_contact(), PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, peerl, sip_peer::prefs, sip_pvt::rtp, sip_peer::secret, sip_cancel_destroy(), sip_destroy_peer(), SIP_NAT, SIP_PAGE2_DYNAMIC, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_PKT_IGNORE, SIP_REGISTER, strsep(), t, temp_peer(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), update_peer(), and XMIT_UNRELIABLE.
08268 { 08269 enum check_auth_result res = AUTH_NOT_FOUND; 08270 struct sip_peer *peer; 08271 char tmp[256]; 08272 char *name, *c; 08273 char *t; 08274 char *domain; 08275 08276 /* Terminate URI */ 08277 t = uri; 08278 while(*t && (*t > 32) && (*t != ';')) 08279 t++; 08280 *t = '\0'; 08281 08282 ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp)); 08283 if (pedanticsipchecking) 08284 ast_uri_decode(tmp); 08285 08286 c = get_in_brackets(tmp); 08287 c = strsep(&c, ";"); /* Ditch ;user=phone */ 08288 08289 if (!strncmp(c, "sip:", 4)) { 08290 name = c + 4; 08291 } else { 08292 name = c; 08293 ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 08294 } 08295 08296 /* Strip off the domain name */ 08297 if ((c = strchr(name, '@'))) { 08298 *c++ = '\0'; 08299 domain = c; 08300 if ((c = strchr(domain, ':'))) /* Remove :port */ 08301 *c = '\0'; 08302 if (!AST_LIST_EMPTY(&domain_list)) { 08303 if (!check_sip_domain(domain, NULL, 0)) { 08304 transmit_response(p, "404 Not found (unknown domain)", &p->initreq); 08305 return AUTH_UNKNOWN_DOMAIN; 08306 } 08307 } 08308 } 08309 08310 ast_string_field_set(p, exten, name); 08311 build_contact(p); 08312 peer = find_peer(name, NULL, 1); 08313 if (!(peer && ast_apply_ha(peer->ha, sin))) { 08314 /* Peer fails ACL check */ 08315 if (peer) 08316 ASTOBJ_UNREF(peer, sip_destroy_peer); 08317 peer = NULL; 08318 } 08319 if (peer) { 08320 /* Set Frame packetization */ 08321 if (p->rtp) { 08322 ast_rtp_codec_setpref(p->rtp, &peer->prefs); 08323 p->autoframing = peer->autoframing; 08324 } 08325 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) { 08326 ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name); 08327 } else { 08328 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT); 08329 transmit_response(p, "100 Trying", req); 08330 if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, ast_test_flag(req, SIP_PKT_IGNORE)))) { 08331 sip_cancel_destroy(p); 08332 08333 /* We have a succesful registration attemp with proper authentication, 08334 now, update the peer */ 08335 switch (parse_register_contact(p, peer, req)) { 08336 case PARSE_REGISTER_FAILED: 08337 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08338 transmit_response_with_date(p, "400 Bad Request", req); 08339 peer->lastmsgssent = -1; 08340 res = 0; 08341 break; 08342 case PARSE_REGISTER_QUERY: 08343 transmit_response_with_date(p, "200 OK", req); 08344 peer->lastmsgssent = -1; 08345 res = 0; 08346 break; 08347 case PARSE_REGISTER_UPDATE: 08348 update_peer(peer, p->expiry); 08349 /* Say OK and ask subsystem to retransmit msg counter */ 08350 transmit_response_with_date(p, "200 OK", req); 08351 if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) 08352 peer->lastmsgssent = -1; 08353 res = 0; 08354 break; 08355 } 08356 } 08357 } 08358 } 08359 if (!peer && autocreatepeer) { 08360 /* Create peer if we have autocreate mode enabled */ 08361 peer = temp_peer(name); 08362 if (peer) { 08363 ASTOBJ_CONTAINER_LINK(&peerl, peer); 08364 sip_cancel_destroy(p); 08365 switch (parse_register_contact(p, peer, req)) { 08366 case PARSE_REGISTER_FAILED: 08367 ast_log(LOG_WARNING, "Failed to parse contact info\n"); 08368 transmit_response_with_date(p, "400 Bad Request", req); 08369 peer->lastmsgssent = -1; 08370 res = 0; 08371 break; 08372 case PARSE_REGISTER_QUERY: 08373 transmit_response_with_date(p, "200 OK", req); 08374 peer->lastmsgssent = -1; 08375 res = 0; 08376 break; 08377 case PARSE_REGISTER_UPDATE: 08378 /* Say OK and ask subsystem to retransmit msg counter */ 08379 transmit_response_with_date(p, "200 OK", req); 08380 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name); 08381 peer->lastmsgssent = -1; 08382 res = 0; 08383 break; 08384 } 08385 } 08386 } 08387 if (!res) { 08388 ast_device_state_changed("SIP/%s", peer->name); 08389 } 08390 if (res < 0) { 08391 switch (res) { 08392 case AUTH_SECRET_FAILED: 08393 /* Wrong password in authentication. Go away, don't try again until you fixed it */ 08394 transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); 08395 break; 08396 case AUTH_USERNAME_MISMATCH: 08397 /* Username and digest username does not match. 08398 Asterisk uses the From: username for authentication. We need the 08399 users to use the same authentication user name until we support 08400 proper authentication by digest auth name */ 08401 transmit_response(p, "403 Authentication user name does not match account name", &p->initreq); 08402 break; 08403 case AUTH_NOT_FOUND: 08404 if (global_alwaysauthreject) { 08405 transmit_fake_auth_response(p, &p->initreq, 1); 08406 } else { 08407 /* URI not found */ 08408 transmit_response(p, "404 Not found", &p->initreq); 08409 } 08410 break; 08411 default: 08412 break; 08413 } 08414 if (option_debug > 1) { 08415 const char *reason = ""; 08416 08417 switch (res) { 08418 case AUTH_SECRET_FAILED: 08419 reason = "Bad password"; 08420 break; 08421 case AUTH_USERNAME_MISMATCH: 08422 reason = "Bad digest user"; 08423 break; 08424 case AUTH_NOT_FOUND: 08425 reason = "Peer not found"; 08426 break; 08427 default: 08428 break; 08429 } 08430 ast_log(LOG_DEBUG, "SIP REGISTER attempt failed for %s : %s\n", 08431 peer->name, reason); 08432 } 08433 } 08434 if (peer) 08435 ASTOBJ_UNREF(peer, sip_destroy_peer); 08436 08437 return res; 08438 }
| static char * regstate2str | ( | enum sipregistrystate | regstate | ) | const [static] |
Convert registration state status to string.
Definition at line 7118 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.
07119 { 07120 switch(regstate) { 07121 case REG_STATE_FAILED: 07122 return "Failed"; 07123 case REG_STATE_UNREGISTERED: 07124 return "Unregistered"; 07125 case REG_STATE_REGSENT: 07126 return "Request Sent"; 07127 case REG_STATE_AUTHSENT: 07128 return "Auth. Sent"; 07129 case REG_STATE_REGISTERED: 07130 return "Registered"; 07131 case REG_STATE_REJECTED: 07132 return "Rejected"; 07133 case REG_STATE_TIMEOUT: 07134 return "Timeout"; 07135 case REG_STATE_NOAUTH: 07136 return "No Authentication"; 07137 default: 07138 return "Unknown"; 07139 } 07140 }
| static int reload | ( | void | ) | [static] |
Part of Asterisk module interface.
Definition at line 17286 of file chan_sip.c.
References sip_reload().
17287 { 17288 return sip_reload(0, 0, NULL); 17289 }
| 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 16197 of file chan_sip.c.
References ahp, ast_clear_flag, ast_config_AST_SYSTEM_NAME, ast_config_load(), ast_copy_flags, AST_FLAGS_ALL, ast_jb_read_conf(), ast_log(), AST_MAX_CONTEXT, ast_set_flag, ast_strlen_zero(), ast_true(), ast_variable_browse(), bindaddr, context, DEFAULT_ALLOW_EXT_DOM, DEFAULT_ALLOWGUEST, DEFAULT_AUTOCREATEPEER, DEFAULT_CALLERID, DEFAULT_COMPACTHEADERS, DEFAULT_CONTEXT, DEFAULT_EXPIRY, default_jbconf, DEFAULT_MAX_CALL_BITRATE, DEFAULT_MOHINTERPRET, DEFAULT_MOHSUGGEST, DEFAULT_MWITIME, DEFAULT_NOTIFYMIME, DEFAULT_NOTIFYRINGING, DEFAULT_PEDANTIC, default_prefs, DEFAULT_QUALIFY, DEFAULT_REALM, DEFAULT_REGISTRATION_TIMEOUT, DEFAULT_SRVLOOKUP, DEFAULT_T1MIN, DEFAULT_TOS_AUDIO, DEFAULT_TOS_SIP, DEFAULT_TOS_VIDEO, DEFAULT_USERAGENT, DEFAULT_VMEXTEN, externexpire, externhost, externip, externrefresh, FALSE, global_flags, global_jbconf, handle_common_options(), hp, localaddr, LOG_NOTICE, ast_variable::name, ast_variable::next, ourport, outboundproxyip, SIP_CAN_REINVITE, SIP_DTMF_RFC2833, SIP_NAT_RFC3581, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DEBUG_CONFIG, SIP_PAGE2_DEBUG_CONSOLE, SIP_PAGE2_RTUPDATE, SIP_PAGE2_VIDEOSUPPORT, STANDARD_SIP_PORT, TRANSFER_OPENFORALL, and ast_variable::value.
16198 { 16199 struct ast_config *cfg, *ucfg; 16200 struct ast_variable *v; 16201 struct sip_peer *peer; 16202 struct sip_user *user; 16203 struct ast_hostent ahp; 16204 char *cat, *stringp, *context, *oldregcontext; 16205 char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT]; 16206 struct hostent *hp; 16207 int format; 16208 struct ast_flags dummy[2]; 16209 int auto_sip_domains = FALSE; 16210 struct sockaddr_in old_bindaddr = bindaddr; 16211 int registry_count = 0, peer_count = 0, user_count = 0; 16212 unsigned int temp_tos = 0; 16213 struct ast_flags debugflag = {0}; 16214 16215 cfg = ast_config_load(config); 16216 16217 /* We *must* have a config file otherwise stop immediately */ 16218 if (!cfg) { 16219 ast_log(LOG_NOTICE, "Unable to load config %s\n", config); 16220 return -1; 16221 } 16222 16223 /* Initialize copy of current global_regcontext for later use in removing stale contexts */ 16224 ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); 16225 oldregcontext = oldcontexts; 16226 16227 /* Clear all flags before setting default values */ 16228 /* Preserve debugging settings for console */ 16229 ast_copy_flags(&debugflag, &global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 16230 ast_clear_flag(&global_flags[0], AST_FLAGS_ALL); 16231 ast_clear_flag(&global_flags[1], AST_FLAGS_ALL); 16232 ast_copy_flags(&global_flags[1], &debugflag, SIP_PAGE2_DEBUG_CONSOLE); 16233 16234 /* Reset IP addresses */ 16235 memset(&bindaddr, 0, sizeof(bindaddr)); 16236 memset(&localaddr, 0, sizeof(localaddr)); 16237 memset(&externip, 0, sizeof(externip)); 16238 memset(&default_prefs, 0 , sizeof(default_prefs)); 16239 outboundproxyip.sin_port = htons(STANDARD_SIP_PORT); 16240 outboundproxyip.sin_family = AF_INET; /* Type of address: IPv4 */ 16241 ourport = STANDARD_SIP_PORT; 16242 srvlookup = DEFAULT_SRVLOOKUP; 16243 global_tos_sip = DEFAULT_TOS_SIP; 16244 global_tos_audio = DEFAULT_TOS_AUDIO; 16245 global_tos_video = DEFAULT_TOS_VIDEO; 16246 externhost[0] = '\0'; /* External host name (for behind NAT DynDNS support) */ 16247 externexpire = 0; /* Expiration for DNS re-issuing */ 16248 externrefresh = 10; 16249 memset(&outboundproxyip, 0, sizeof(outboundproxyip)); 16250 16251 /* Reset channel settings to default before re-configuring */ 16252 allow_external_domains = DEFAULT_ALLOW_EXT_DOM; /* Allow external invites */ 16253 global_regcontext[0] = '\0'; 16254 expiry = DEFAULT_EXPIRY; 16255 global_notifyringing = DEFAULT_NOTIFYRINGING; 16256 global_limitonpeers = FALSE; 16257 global_directrtpsetup = FALSE; /* Experimental feature, disabled by default */ 16258 global_notifyhold = FALSE; 16259 global_alwaysauthreject = 0; 16260 global_allowsubscribe = FALSE; 16261 ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent)); 16262 ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime)); 16263 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) 16264 ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm)); 16265 else 16266 ast_copy_string(global_realm, ast_config_AST_SYSTEM_NAME, sizeof(global_realm)); 16267 ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid)); 16268 compactheaders = DEFAULT_COMPACTHEADERS; 16269 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 16270 global_regattempts_max = 0; 16271 pedanticsipchecking = DEFAULT_PEDANTIC; 16272 global_mwitime = DEFAULT_MWITIME; 16273 autocreatepeer = DEFAULT_AUTOCREATEPEER; 16274 global_autoframing = 0; 16275 global_allowguest = DEFAULT_ALLOWGUEST; 16276 global_rtptimeout = 0; 16277 global_rtpholdtimeout = 0; 16278 global_rtpkeepalive = 0; 16279 global_allowtransfer = TRANSFER_OPENFORALL; /* Merrily accept all transfers by default */ 16280 global_rtautoclear = 120; 16281 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE); /* Default for peers, users: TRUE */ 16282 ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP); /* Default for peers, users: TRUE */ 16283 ast_set_flag(&global_flags[1], SIP_PAGE2_RTUPDATE); 16284 16285 /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for peers and users */ 16286 ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context)); 16287 default_subscribecontext[0] = '\0'; 16288 default_language[0] = '\0'; 16289 default_fromdomain[0] = '\0'; 16290 default_qualify = DEFAULT_QUALIFY; 16291 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 16292 ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret)); 16293 ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest)); 16294 ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten)); 16295 ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */ 16296 ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */ 16297 ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */ 16298 16299 /* Debugging settings, always default to off */ 16300 dumphistory = FALSE; 16301 recordhistory = FALSE; 16302 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 16303 16304 /* Misc settings for the channel */ 16305 global_relaxdtmf = FALSE; 16306 global_callevents = FALSE; 16307 global_t1min = DEFAULT_T1MIN; 16308 16309 global_matchexterniplocally = FALSE; 16310 16311 /* Copy the default jb config over global_jbconf */ 16312 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 16313 16314 ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT); 16315 16316 /* Read the [general] config section of sip.conf (or from realtime config) */ 16317 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 16318 if (handle_common_options(&global_flags[0], &dummy[0], v)) 16319 continue; 16320 /* handle jb conf */ 16321 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 16322 continue; 16323 16324 /* Create the interface list */ 16325 if (!strcasecmp(v->name, "context")) { 16326 ast_copy_string(default_context, v->value, sizeof(default_context)); 16327 } else if (!strcasecmp(v->name, "allowguest")) { 16328 global_allowguest = ast_true(v->value) ? 1 : 0; 16329 } else if (!strcasecmp(v->name, "realm")) { 16330 ast_copy_string(global_realm, v->value, sizeof(global_realm)); 16331 } else if (!strcasecmp(v->name, "useragent")) { 16332 ast_copy_string(global_useragent, v->value, sizeof(global_useragent)); 16333 if (option_debug) 16334 ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent); 16335 } else if (!strcasecmp(v->name, "allowtransfer")) { 16336 global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED; 16337 } else if (!strcasecmp(v->name, "rtcachefriends")) { 16338 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS); 16339 } else if (!strcasecmp(v->name, "rtsavesysname")) { 16340 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTSAVE_SYSNAME); 16341 } else if (!strcasecmp(v->name, "rtupdate")) { 16342 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTUPDATE); 16343 } else if (!strcasecmp(v->name, "ignoreregexpire")) { 16344 ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_IGNOREREGEXPIRE); 16345 } else if (!strcasecmp(v->name, "t1min")) { 16346 global_t1min = atoi(v->value); 16347 } else if (!strcasecmp(v->name, "rtautoclear")) { 16348 int i = atoi(v->value); 16349 if (i > 0) 16350 global_rtautoclear = i; 16351 else 16352 i = 0; 16353 ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR); 16354 } else if (!strcasecmp(v->name, "usereqphone")) { 16355 ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE); 16356 } else if (!strcasecmp(v->name, "relaxdtmf")) { 16357 global_relaxdtmf = ast_true(v->value); 16358 } else if (!strcasecmp(v->name, "checkmwi")) { 16359 if ((sscanf(v->value, "%d", &global_mwitime) != 1) || (global_mwitime < 0)) { 16360 ast_log(LOG_WARNING, "'%s' is not a valid MWI time setting at line %d. Using default (10).\n", v->value, v->lineno); 16361 global_mwitime = DEFAULT_MWITIME; 16362 } 16363 } else if (!strcasecmp(v->name, "vmexten")) { 16364 ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten)); 16365 } else if (!strcasecmp(v->name, "rtptimeout")) { 16366 if ((sscanf(v->value, "%d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) { 16367 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16368 global_rtptimeout = 0; 16369 } 16370 } else if (!strcasecmp(v->name, "rtpholdtimeout")) { 16371 if ((sscanf(v->value, "%d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) { 16372 ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d. Using default.\n", v->value, v->lineno); 16373 global_rtpholdtimeout = 0; 16374 } 16375 } else if (!strcasecmp(v->name, "rtpkeepalive")) { 16376 if ((sscanf(v->value, "%d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) { 16377 ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); 16378 global_rtpkeepalive = 0; 16379 } 16380 } else if (!strcasecmp(v->name, "compactheaders")) { 16381 compactheaders = ast_true(v->value); 16382 } else if (!strcasecmp(v->name, "notifymimetype")) { 16383 ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime)); 16384 } else if (!strncasecmp(v->name, "limitonpeer", 11)) { 16385 global_limitonpeers = ast_true(v->value); 16386 } else if (!strcasecmp(v->name, "directrtpsetup")) { 16387 global_directrtpsetup = ast_true(v->value); 16388 } else if (!strcasecmp(v->name, "notifyringing")) { 16389 global_notifyringing = ast_true(v->value); 16390 } else if (!strcasecmp(v->name, "notifyhold")) { 16391 global_notifyhold = ast_true(v->value); 16392 } else if (!strcasecmp(v->name, "alwaysauthreject")) { 16393 global_alwaysauthreject = ast_true(v->value); 16394 } else if (!strcasecmp(v->name, "mohinterpret") 16395 || !strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) { 16396 ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret)); 16397 } else if (!strcasecmp(v->name, "mohsuggest")) { 16398 ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest)); 16399 } else if (!strcasecmp(v->name, "language")) { 16400 ast_copy_string(default_language, v->value, sizeof(default_language)); 16401 } else if (!strcasecmp(v->name, "regcontext")) { 16402 ast_copy_string(newcontexts, v->value, sizeof(newcontexts)); 16403 stringp = newcontexts; 16404 /* Let's remove any contexts that are no longer defined in regcontext */ 16405 cleanup_stale_contexts(stringp, oldregcontext); 16406 /* Create contexts if they don't exist already */ 16407 while ((context = strsep(&stringp, "&"))) { 16408 if (!ast_context_find(context)) 16409 ast_context_create(NULL, context,"SIP"); 16410 } 16411 ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext)); 16412 } else if (!strcasecmp(v->name, "callerid")) { 16413 ast_copy_string(default_callerid, v->value, sizeof(default_callerid)); 16414 } else if (!strcasecmp(v->name, "fromdomain")) { 16415 ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain)); 16416 } else if (!strcasecmp(v->name, "outboundproxy")) { 16417 if (ast_get_ip_or_srv(&outboundproxyip, v->value, srvlookup ? "_sip._udp" : NULL) < 0) 16418 ast_log(LOG_WARNING, "Unable to locate host '%s'\n", v->value); 16419 } else if (!strcasecmp(v->name, "outboundproxyport")) { 16420 /* Port needs to be after IP */ 16421 sscanf(v->value, "%d", &format); 16422 outboundproxyip.sin_port = htons(format); 16423 } else if (!strcasecmp(v->name, "autocreatepeer")) { 16424 autocreatepeer = ast_true(v->value); 16425 } else if (!strcasecmp(v->name, "srvlookup")) { 16426 srvlookup = ast_true(v->value); 16427 } else if (!strcasecmp(v->name, "pedantic")) { 16428 pedanticsipchecking = ast_true(v->value); 16429 } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) { 16430 max_expiry = atoi(v->value); 16431 if (max_expiry < 1) 16432 max_expiry = DEFAULT_MAX_EXPIRY; 16433 } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) { 16434 min_expiry = atoi(v->value); 16435 if (min_expiry < 1) 16436 min_expiry = DEFAULT_MIN_EXPIRY; 16437 } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) { 16438 default_expiry = atoi(v->value); 16439 if (default_expiry < 1) 16440 default_expiry = DEFAULT_DEFAULT_EXPIRY; 16441 } else if (!strcasecmp(v->name, "sipdebug")) { /* XXX maybe ast_set2_flags ? */ 16442 if (ast_true(v->value)) 16443 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONFIG); 16444 } else if (!strcasecmp(v->name, "dumphistory")) { 16445 dumphistory = ast_true(v->value); 16446 } else if (!strcasecmp(v->name, "recordhistory")) { 16447 recordhistory = ast_true(v->value); 16448 } else if (!strcasecmp(v->name, "registertimeout")) { 16449 global_reg_timeout = atoi(v->value); 16450 if (global_reg_timeout < 1) 16451 global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT; 16452 } else if (!strcasecmp(v->name, "registerattempts")) { 16453 global_regattempts_max = atoi(v->value); 16454 } else if (!strcasecmp(v->name, "bindaddr")) { 16455 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 16456 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 16457 } else { 16458 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 16459 } 16460 } else if (!strcasecmp(v->name, "localnet")) { 16461 struct ast_ha *na; 16462 if (!(na = ast_append_ha("d", v->value, localaddr))) 16463 ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value); 16464 else 16465 localaddr = na; 16466 } else if (!strcasecmp(v->name, "localmask")) { 16467 ast_log(LOG_WARNING, "Use of localmask is no long supported -- use localnet with mask syntax\n"); 16468 } else if (!strcasecmp(v->name, "externip")) { 16469 if (!(hp = ast_gethostbyname(v->value, &ahp))) 16470 ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value); 16471 else 16472 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 16473 externexpire = 0; 16474 } else if (!strcasecmp(v->name, "externhost")) { 16475 ast_copy_string(externhost, v->value, sizeof(externhost)); 16476 if (!(hp = ast_gethostbyname(externhost, &ahp))) 16477 ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost); 16478 else 16479 memcpy(&externip.sin_addr, hp->h_addr, sizeof(externip.sin_addr)); 16480 externexpire = time(NULL); 16481 } else if (!strcasecmp(v->name, "externrefresh")) { 16482 if (sscanf(v->value, "%d", &externrefresh) != 1) { 16483 ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno); 16484 externrefresh = 10; 16485 } 16486 } else if (!strcasecmp(v->name, "allow")) { 16487 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 1); 16488 } else if (!strcasecmp(v->name, "disallow")) { 16489 ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, 0); 16490 } else if (!strcasecmp(v->name, "autoframing")) { 16491 global_autoframing = ast_true(v->value); 16492 } else if (!strcasecmp(v->name, "allowexternaldomains")) { 16493 allow_external_domains = ast_true(v->value); 16494 } else if (!strcasecmp(v->name, "autodomain")) { 16495 auto_sip_domains = ast_true(v->value); 16496 } else if (!strcasecmp(v->name, "domain")) { 16497 char *domain = ast_strdupa(v->value); 16498 char *context = strchr(domain, ','); 16499 16500 if (context) 16501 *context++ = '\0'; 16502 16503 if (option_debug && ast_strlen_zero(context)) 16504 ast_log(LOG_DEBUG, "No context specified at line %d for domain '%s'\n", v->lineno, domain); 16505 if (ast_strlen_zero(domain)) 16506 ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno); 16507 else 16508 add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : ""); 16509 } else if (!strcasecmp(v->name, "register")) { 16510 if (sip_register(v->value, v->lineno) == 0) 16511 registry_count++; 16512 } else if (!strcasecmp(v->name, "tos")) { 16513 if (!ast_str2tos(v->value, &temp_tos)) { 16514 global_tos_sip = temp_tos; 16515 global_tos_audio = temp_tos; 16516 global_tos_video = temp_tos; 16517 ast_log(LOG_WARNING, "tos value at line %d is deprecated. See doc/ip-tos.txt for more information.\n", v->lineno); 16518 } else 16519 ast_log(LOG_WARNING, "Invalid tos value at line %d, See doc/ip-tos.txt for more information.\n", v->lineno); 16520 } else if (!strcasecmp(v->name, "tos_sip")) { 16521 if (ast_str2tos(v->value, &global_tos_sip)) 16522 ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, recommended value is 'cs3'. See doc/ip-tos.txt.\n", v->lineno); 16523 } else if (!strcasecmp(v->name, "tos_audio")) { 16524 if (ast_str2tos(v->value, &global_tos_audio)) 16525 ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, recommended value is 'ef'. See doc/ip-tos.txt.\n", v->lineno); 16526 } else if (!strcasecmp(v->name, "tos_video")) { 16527 if (ast_str2tos(v->value, &global_tos_video)) 16528 ast_log(LOG_WARNING, "Invalid tos_video value at line %d, recommended value is 'af41'. See doc/ip-tos.txt.\n", v->lineno); 16529 } else if (!strcasecmp(v->name, "bindport")) { 16530 if (sscanf(v->value, "%d", &ourport) == 1) { 16531 bindaddr.sin_port = htons(ourport); 16532 } else { 16533 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 16534 } 16535 } else if (!strcasecmp(v->name, "qualify")) { 16536 if (!strcasecmp(v->value, "no")) { 16537 default_qualify = 0; 16538 } else if (!strcasecmp(v->value, "yes")) { 16539 default_qualify = DEFAULT_MAXMS; 16540 } else if (sscanf(v->value, "%d", &default_qualify) != 1) { 16541 ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno); 16542 default_qualify = 0; 16543 } 16544 } else if (!strcasecmp(v->name, "callevents")) { 16545 global_callevents = ast_true(v->value); 16546 } else if (!strcasecmp(v->name, "maxcallbitrate")) { 16547 default_maxcallbitrate = atoi(v->value); 16548 if (default_maxcallbitrate < 0) 16549 default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE; 16550 } else if (!strcasecmp(v->name, "matchexterniplocally")) { 16551 global_matchexterniplocally = ast_true(v->value); 16552 } 16553 } 16554 16555 if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) { 16556 ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n"); 16557 allow_external_domains = 1; 16558 } 16559 16560 /* Build list of authentication to various SIP realms, i.e. service providers */ 16561 for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { 16562 /* Format for authentication is auth = username:password@realm */ 16563 if (!strcasecmp(v->name, "auth")) 16564 authl = add_realm_authentication(authl, v->value, v->lineno); 16565 } 16566 16567 ucfg = ast_config_load("users.conf"); 16568 if (ucfg) { 16569 struct ast_variable *gen; 16570 int genhassip, genregistersip; 16571 const char *hassip, *registersip; 16572 16573 genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip")); 16574 genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip")); 16575 gen = ast_variable_browse(ucfg, "general"); 16576 cat = ast_category_browse(ucfg, NULL); 16577 while (cat) { 16578 if (strcasecmp(cat, "general")) { 16579 hassip = ast_variable_retrieve(ucfg, cat, "hassip"); 16580 registersip = ast_variable_retrieve(ucfg, cat, "registersip"); 16581 if (ast_true(hassip) || (!hassip && genhassip)) { 16582 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 16583 if (peer) { 16584 ASTOBJ_CONTAINER_LINK(&peerl,peer); 16585 ASTOBJ_UNREF(peer, sip_destroy_peer); 16586 peer_count++; 16587 } 16588 } 16589 if (ast_true(registersip) || (!registersip && genregistersip)) { 16590 char tmp[256]; 16591 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 16592 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 16593 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 16594 const char *contact = ast_variable_retrieve(ucfg, cat, "contact"); 16595 if (!host) 16596 host = ast_variable_retrieve(ucfg, "general", "host"); 16597 if (!username) 16598 username = ast_variable_retrieve(ucfg, "general", "username"); 16599 if (!secret) 16600 secret = ast_variable_retrieve(ucfg, "general", "secret"); 16601 if (!contact) 16602 contact = "s"; 16603 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 16604 if (!ast_strlen_zero(secret)) 16605 snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact); 16606 else 16607 snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact); 16608 if (sip_register(tmp, 0) == 0) 16609 registry_count++; 16610 } 16611 } 16612 } 16613 cat = ast_category_browse(ucfg, cat); 16614 } 16615 ast_config_destroy(ucfg); 16616 } 16617 16618 16619 /* Load peers, users and friends */ 16620 cat = NULL; 16621 while ( (cat = ast_category_browse(cfg, cat)) ) { 16622 const char *utype; 16623 if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication")) 16624 continue; 16625 utype = ast_variable_retrieve(cfg, cat, "type"); 16626 if (!utype) { 16627 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 16628 continue; 16629 } else { 16630 int is_user = 0, is_peer = 0; 16631 if (!strcasecmp(utype, "user")) 16632 is_user = 1; 16633 else if (!strcasecmp(utype, "friend")) 16634 is_user = is_peer = 1; 16635 else if (!strcasecmp(utype, "peer")) 16636 is_peer = 1; 16637 else { 16638 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf"); 16639 continue; 16640 } 16641 if (is_user) { 16642 user = build_user(cat, ast_variable_browse(cfg, cat), 0); 16643 if (user) { 16644 ASTOBJ_CONTAINER_LINK(&userl,user); 16645 ASTOBJ_UNREF(user, sip_destroy_user); 16646 user_count++; 16647 } 16648 } 16649 if (is_peer) { 16650 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 16651 if (peer) { 16652 ASTOBJ_CONTAINER_LINK(&peerl,peer); 16653 ASTOBJ_UNREF(peer, sip_destroy_peer); 16654 peer_count++; 16655 } 16656 } 16657 } 16658 } 16659 if (ast_find_ourip(&__ourip, bindaddr)) { 16660 ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n"); 16661 return 0; 16662 } 16663 if (!ntohs(bindaddr.sin_port)) 16664 bindaddr.sin_port = ntohs(STANDARD_SIP_PORT); 16665 bindaddr.sin_family = AF_INET; 16666 ast_mutex_lock(&netlock); 16667 if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) { 16668 close(sipsock); 16669 sipsock = -1; 16670 } 16671 if (sipsock < 0) { 16672 sipsock = socket(AF_INET, SOCK_DGRAM, 0); 16673 if (sipsock < 0) { 16674 ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno)); 16675 return -1; 16676 } else { 16677 /* Allow SIP clients on the same host to access us: */ 16678 const int reuseFlag = 1; 16679 16680 setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR, 16681 (const char*)&reuseFlag, 16682 sizeof reuseFlag); 16683 16684 ast_enable_packet_fragmentation(sipsock); 16685 16686 if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 16687 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 16688 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port), 16689 strerror(errno)); 16690 close(sipsock); 16691 sipsock = -1; 16692 } else { 16693 if (option_verbose > 1) { 16694 ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n", 16695 ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 16696 ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global_tos_sip)); 16697 } 16698 if (setsockopt(sipsock, IPPROTO_IP, IP_TOS, &global_tos_sip, sizeof(global_tos_sip))) 16699 ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global_tos_sip)); 16700 } 16701 } 16702 } 16703 ast_mutex_unlock(&netlock); 16704 16705 /* Add default domains - host name, IP address and IP:port */ 16706 /* Only do this if user added any sip domain with "localdomains" */ 16707 /* In order to *not* break backwards compatibility */ 16708 /* Some phones address us at IP only, some with additional port number */ 16709 if (auto_sip_domains) { 16710 char temp[MAXHOSTNAMELEN]; 16711 16712 /* First our default IP address */ 16713 if (bindaddr.sin_addr.s_addr) 16714 add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL); 16715 else 16716 ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n"); 16717 16718 /* Our extern IP address, if configured */ 16719 if (externip.sin_addr.s_addr) 16720 add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL); 16721 16722 /* Extern host name (NAT traversal support) */ 16723 if (!ast_strlen_zero(externhost)) 16724 add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL); 16725 16726 /* Our host name */ 16727 if (!gethostname(temp, sizeof(temp))) 16728 add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL); 16729 } 16730 16731 /* Release configuration from memory */ 16732 ast_config_destroy(cfg); 16733 16734 /* Load the list of manual NOTIFY types to support */ 16735 if (notify_types) 16736 ast_config_destroy(notify_types); 16737 notify_types = ast_config_load(notify_config); 16738 16739 /* Done, tell the manager */ 16740 manager_event(EVENT_FLAG_SYSTEM, "ChannelReload", "Channel: SIP\r\nReloadReason: %s\r\nRegistry_Count: %d\r\nPeer_Count: %d\r\nUser_Count: %d\r\n\r\n", channelreloadreason2txt(reason), registry_count, peer_count, user_count); 16741 16742 return 0; 16743 }
| 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 11113 of file chan_sip.c.
References ast_log(), ast_string_field_index, ast_string_field_index_set, ast_string_field_set, ast_strlen_zero(), build_reply_digest(), get_header(), key(), keys, LOG_WARNING, sip_registry::noncecount, sip_pvt::noncecount, sip_pvt::registry, and strsep().
Referenced by do_proxy_auth(), and do_register_auth().
11114 { 11115 char tmp[512]; 11116 char *c; 11117 char oldnonce[256]; 11118 11119 /* table of recognised keywords, and places where they should be copied */ 11120 const struct x { 11121 const char *key; 11122 int field_index; 11123 } *i, keys[] = { 11124 { "realm=", ast_string_field_index(p, realm) }, 11125 { "nonce=", ast_string_field_index(p, nonce) }, 11126 { "opaque=", ast_string_field_index(p, opaque) }, 11127 { "qop=", ast_string_field_index(p, qop) }, 11128 { "domain=", ast_string_field_index(p, domain) }, 11129 { NULL, 0 }, 11130 }; 11131 11132 ast_copy_string(tmp, get_header(req, header), sizeof(tmp)); 11133 if (ast_strlen_zero(tmp)) 11134 return -1; 11135 if (strncasecmp(tmp, "Digest ", strlen("Digest "))) { 11136 ast_log(LOG_WARNING, "missing Digest.\n"); 11137 return -1; 11138 } 11139 c = tmp + strlen("Digest "); 11140 ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce)); 11141 while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */ 11142 for (i = keys; i->key != NULL; i++) { 11143 char *src, *separator; 11144 if (strncasecmp(c, i->key, strlen(i->key)) != 0) 11145 continue; 11146 /* Found. Skip keyword, take text in quotes or up to the separator. */ 11147 c += strlen(i->key); 11148 if (*c == '"') { 11149 src = ++c; 11150 separator = "\""; 11151 } else { 11152 src = c; 11153 separator = ","; 11154 } 11155 strsep(&c, separator); /* clear separator and move ptr */ 11156 ast_string_field_index_set(p, i->field_index, src); 11157 break; 11158 } 11159 if (i->key == NULL) /* not found, try ',' */ 11160 strsep(&c, ","); 11161 } 11162 /* Reset nonce count */ 11163 if (strcmp(p->nonce, oldnonce)) 11164 p->noncecount = 0; 11165 11166 /* Save auth data for following registrations */ 11167 if (p->registry) { 11168 struct sip_registry *r = p->registry; 11169 11170 if (strcmp(r->nonce, p->nonce)) { 11171 ast_string_field_set(r, realm, p->realm); 11172 ast_string_field_set(r, nonce, p->nonce); 11173 ast_string_field_set(r, domain, p->domain); 11174 ast_string_field_set(r, opaque, p->opaque); 11175 ast_string_field_set(r, qop, p->qop); 11176 r->noncecount = 0; 11177 } 11178 } 11179 return build_reply_digest(p, sipmethod, digest, digest_len); 11180 }
| 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 5633 of file chan_sip.c.
References add_header(), add_route(), ast_log(), ast_random(), ast_strlen_zero(), ast_test_flag, sip_pvt::branch, build_via(), copy_header(), DEFAULT_MAX_FORWARDS, FALSE, sip_pvt::flags, get_header(), get_in_brackets(), sip_route::hop, init_req(), sip_pvt::initreq, sip_pvt::lastmsg, LOG_DEBUG, sip_route::next, sip_pvt::ocseq, sip_request::rlPart2, sip_pvt::route, set_destination(), SIP_ACK, SIP_BYE, SIP_CANCEL, SIP_MESSAGE, sip_methods, SIP_OUTGOING, sipdebug, strcasestr(), strsep(), sip_pvt::tag, text, cfsip_methods::text, and TRUE.
05634 { 05635 struct sip_request *orig = &p->initreq; 05636 char stripped[80]; 05637 char tmp[80]; 05638 char newto[256]; 05639 const char *c; 05640 const char *ot, *of; 05641 int is_strict = FALSE; /*!< Strict routing flag */ 05642 05643 memset(req, 0, sizeof(struct sip_request)); 05644 05645 snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text); 05646 05647 if (!seqno) { 05648 p->ocseq++; 05649 seqno = p->ocseq; 05650 } 05651 05652 if (newbranch) { 05653 p->branch ^= ast_random(); 05654 build_via(p); 05655 } 05656 05657 /* Check for strict or loose router */ 05658 if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL) { 05659 is_strict = TRUE; 05660 if (sipdebug) 05661 ast_log(LOG_DEBUG, "Strict routing enforced for session %s\n", p->callid); 05662 } 05663 05664 if (sipmethod == SIP_CANCEL) 05665 c = p->initreq.rlPart2; /* Use original URI */ 05666 else if (sipmethod == SIP_ACK) { 05667 /* Use URI from Contact: in 200 OK (if INVITE) 05668 (we only have the contacturi on INVITEs) */ 05669 if (!ast_strlen_zero(p->okcontacturi)) 05670 c = is_strict ? p->route->hop : p->okcontacturi; 05671 else 05672 c = p->initreq.rlPart2; 05673 } else if (!ast_strlen_zero(p->okcontacturi)) 05674 c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */ 05675 else if (!ast_strlen_zero(p->uri)) 05676 c = p->uri; 05677 else { 05678 char *n; 05679 /* We have no URI, use To: or From: header as URI (depending on direction) */ 05680 ast_copy_string(stripped, get_header(orig, (ast_test_flag(&p->flags[0], SIP_OUTGOING)) ? "To" : "From"), 05681 sizeof(stripped)); 05682 n = get_in_brackets(stripped); 05683 c = strsep(&n, ";"); /* trim ; and beyond */ 05684 } 05685 init_req(req, sipmethod, c); 05686 05687 snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text); 05688 05689 add_header(req, "Via", p->via); 05690 if (p->route) { 05691 set_destination(p, p->route->hop); 05692 add_route(req, is_strict ? p->route->next : p->route); 05693 } 05694 05695 ot = get_header(orig, "To"); 05696 of = get_header(orig, "From"); 05697 05698 /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly 05699 as our original request, including tag (or presumably lack thereof) */ 05700 if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) { 05701 /* Add the proper tag if we don't have it already. If they have specified 05702 their tag, use it. Otherwise, use our own tag */ 05703 if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && !ast_strlen_zero(p->theirtag)) 05704 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 05705 else if (!ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05706 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 05707 else 05708 snprintf(newto, sizeof(newto), "%s", ot); 05709 ot = newto; 05710 } 05711 05712 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 05713 add_header(req, "From", of); 05714 add_header(req, "To", ot); 05715 } else { 05716 add_header(req, "From", ot); 05717 add_header(req, "To", of); 05718 } 05719 /* Do not add Contact for MESSAGE, BYE and Cancel requests */ 05720 if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE) 05721 add_header(req, "Contact", p->our_contact); 05722 05723 copy_header(req, orig, "Call-ID"); 05724 add_header(req, "CSeq", tmp); 05725 05726 if (!ast_strlen_zero(global_useragent)) 05727 add_header(req, "User-Agent", global_useragent); 05728 add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 05729 05730 if (!ast_strlen_zero(p->rpid)) 05731 add_header(req, "Remote-Party-ID", p->rpid); 05732 05733 return 0; 05734 }
| 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 5585 of file chan_sip.c.
References add_header(), ALLOWED_METHODS, ast_strlen_zero(), ast_test_flag, copy_all_header(), copy_header(), copy_via_headers(), sip_pvt::expiry, sip_pvt::flags, get_header(), init_resp(), sip_pvt::method, SIP_OUTGOING, SIP_REGISTER, SIP_SUBSCRIBE, strcasestr(), SUPPORTED_EXTENSIONS, and sip_pvt::tag.
05586 { 05587 char newto[256]; 05588 const char *ot; 05589 05590 init_resp(resp, msg); 05591 copy_via_headers(p, resp, req, "Via"); 05592 if (msg[0] == '2') 05593 copy_all_header(resp, req, "Record-Route"); 05594 copy_header(resp, req, "From"); 05595 ot = get_header(req, "To"); 05596 if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) { 05597 /* Add the proper tag if we don't have it already. If they have specified 05598 their tag, use it. Otherwise, use our own tag */ 05599 if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05600 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag); 05601 else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) 05602 snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag); 05603 else 05604 ast_copy_string(newto, ot, sizeof(newto)); 05605 ot = newto; 05606 } 05607 add_header(resp, "To", ot); 05608 copy_header(resp, req, "Call-ID"); 05609 copy_header(resp, req, "CSeq"); 05610 if (!ast_strlen_zero(global_useragent)) 05611 add_header(resp, "User-Agent", global_useragent); 05612 add_header(resp, "Allow", ALLOWED_METHODS); 05613 add_header(resp, "Supported", SUPPORTED_EXTENSIONS); 05614 if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) { 05615 /* For registration responses, we also need expiry and 05616 contact info */ 05617 char tmp[256]; 05618 05619 snprintf(tmp, sizeof(tmp), "%d", p->expiry); 05620 add_header(resp, "Expires", tmp); 05621 if (p->expiry) { /* Only add contact if we have an expiry time */ 05622 char contact[BUFSIZ]; 05623 snprintf(contact, sizeof(contact), "%s;expires=%d", p->our_contact, p->expiry); 05624 add_header(resp, "Contact", contact); /* Not when we unregister */ 05625 } 05626 } else if (msg[0] != '4' && p->our_contact[0]) { 05627 add_header(resp, "Contact", p->our_contact); 05628 } 05629 return 0; 05630 }
| static int restart_monitor | ( | void | ) | [static] |
Start the channel monitor thread.
Definition at line 15180 of file chan_sip.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, and LOG_WARNING.
15181 { 15182 /* If we're supposed to be stopped -- stay stopped */ 15183 if (monitor_thread == AST_PTHREADT_STOP) 15184 return 0; 15185 ast_mutex_lock(&monlock); 15186 if (monitor_thread == pthread_self()) { 15187 ast_mutex_unlock(&monlock); 15188 ast_log(LOG_WARNING, "Cannot kill myself\n"); 15189 return -1; 15190 } 15191 if (monitor_thread != AST_PTHREADT_NULL) { 15192 /* Wake up the thread */ 15193 pthread_kill(monitor_thread, SIGURG); 15194 } else { 15195 /* Start a new monitor */ 15196 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 15197 ast_mutex_unlock(&monlock); 15198 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 15199 return -1; 15200 } 15201 } 15202 ast_mutex_unlock(&monlock); 15203 return 0; 15204 }
| static int retrans_pkt | ( | void * | data | ) | [static] |
Retransmit SIP message if no answer (Called from scheduler).
Definition at line 1850 of file chan_sip.c.
References __sip_xmit(), append_history, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_hangup(), ast_set_flag, ast_test_flag, ast_verbose(), sip_pkt::data, DEFAULT_RETRANS, FLAG_FATAL, FLAG_RESPONSE, sip_pvt::flags, free, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, MAX_RETRANS, sip_pkt::method, sip_pkt::next, option_debug, sip_pvt::owner, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pkt::retrans, sip_pkt::retransid, sip_alreadygone(), sip_debug_test_pvt(), SIP_INVITE, sip_methods, sip_nat_mode(), SIP_NEEDDESTROY, SIP_OPTIONS, sip_real_dst(), sipdebug, cfsip_methods::text, sip_pkt::timer_a, and sip_pkt::timer_t1.
01851 { 01852 struct sip_pkt *pkt = data, *prev, *cur = NULL; 01853 int reschedule = DEFAULT_RETRANS; 01854 01855 /* Lock channel PVT */ 01856 ast_mutex_lock(&pkt->owner->lock); 01857 01858 if (pkt->retrans < MAX_RETRANS) { 01859 pkt->retrans++; 01860 if (!pkt->timer_t1) { /* Re-schedule using timer_a and timer_t1 */ 01861 if (sipdebug && option_debug > 3) 01862 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); 01863 } else { 01864 int siptimer_a; 01865 01866 if (sipdebug && option_debug > 3) 01867 ast_log(LOG_DEBUG, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method); 01868 if (!pkt->timer_a) 01869 pkt->timer_a = 2 ; 01870 else 01871 pkt->timer_a = 2 * pkt->timer_a; 01872 01873 /* For non-invites, a maximum of 4 secs */ 01874 siptimer_a = pkt->timer_t1 * pkt->timer_a; /* Double each time */ 01875 if (pkt->method != SIP_INVITE && siptimer_a > 4000) 01876 siptimer_a = 4000; 01877 01878 /* Reschedule re-transmit */ 01879 reschedule = siptimer_a; 01880 if (option_debug > 3) 01881 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); 01882 } 01883 01884 if (sip_debug_test_pvt(pkt->owner)) { 01885 const struct sockaddr_in *dst = sip_real_dst(pkt->owner); 01886 ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n", 01887 pkt->retrans, sip_nat_mode(pkt->owner), 01888 ast_inet_ntoa(dst->sin_addr), 01889 ntohs(dst->sin_port), pkt->data); 01890 } 01891 01892 append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data); 01893 __sip_xmit(pkt->owner, pkt->data, pkt->packetlen); 01894 ast_mutex_unlock(&pkt->owner->lock); 01895 return reschedule; 01896 } 01897 /* Too many retries */ 01898 if (pkt->owner && pkt->method != SIP_OPTIONS) { 01899 if (ast_test_flag(pkt, FLAG_FATAL) || sipdebug) /* Tell us if it's critical or if we're debugging */ 01900 ast_log(LOG_WARNING, "Maximum retries exceeded on transmission %s for seqno %d (%s %s)\n", pkt->owner->callid, pkt->seqno, (ast_test_flag(pkt, FLAG_FATAL)) ? "Critical" : "Non-critical", (ast_test_flag(pkt, FLAG_RESPONSE)) ? "Response" : "Request"); 01901 } else { 01902 if ((pkt->method == SIP_OPTIONS) && sipdebug) 01903 ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->owner->callid); 01904 } 01905 append_history(pkt->owner, "MaxRetries", "%s", (ast_test_flag(pkt, FLAG_FATAL)) ? "(Critical)" : "(Non-critical)"); 01906 01907 pkt->retransid = -1; 01908 01909 if (ast_test_flag(pkt, FLAG_FATAL)) { 01910 while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) { 01911 ast_mutex_unlock(&pkt->owner->lock); /* SIP_PVT, not channel */ 01912 usleep(1); 01913 ast_mutex_lock(&pkt->owner->lock); 01914 } 01915 if (pkt->owner->owner) { 01916 sip_alreadygone(pkt->owner); 01917 ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pkt->owner->callid); 01918 ast_queue_hangup(pkt->owner->owner); 01919 ast_channel_unlock(pkt->owner->owner); 01920 } else { 01921 /* If no channel owner, destroy now */ 01922 01923 /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */ 01924 if (pkt->method != SIP_OPTIONS) 01925 ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY); 01926 } 01927 } 01928 /* In any case, go ahead and remove the packet */ 01929 for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) { 01930 if (cur == pkt) 01931 break; 01932 } 01933 if (cur) { 01934 if (prev) 01935 prev->next = cur->next; 01936 else 01937 pkt->owner->packets = cur->next; 01938 ast_mutex_unlock(&pkt->owner->lock); 01939 free(cur); 01940 pkt = NULL; 01941 } else 01942 ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n"); 01943 if (pkt) 01944 ast_mutex_unlock(&pkt->owner->lock); 01945 return 0; 01946 }
| 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 2185 of file chan_sip.c.
References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_inet_ntoa(), ast_test_flag, ast_verbose(), sip_request::data, sip_pvt::flags, get_header(), sip_request::len, sip_request::method, parse_copy(), sip_pvt::recv, sip_pvt::sa, sip_debug_test_pvt(), sip_methods, SIP_NAT_ROUTE, SIP_NO_HISTORY, and cfsip_methods::text.
02186 { 02187 int res; 02188 02189 add_blank(req); 02190 if (sip_debug_test_pvt(p)) { 02191 if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE)) 02192 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); 02193 else 02194 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); 02195 } 02196 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02197 struct sip_request tmp; 02198 parse_copy(&tmp, req); 02199 append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text); 02200 } 02201 res = (reliable) ? 02202 __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable > 1), req->method) : 02203 __sip_xmit(p, req->data, req->len); 02204 return res; 02205 }
| 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 2157 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.
02158 { 02159 int res; 02160 02161 add_blank(req); 02162 if (sip_debug_test_pvt(p)) { 02163 const struct sockaddr_in *dst = sip_real_dst(p); 02164 02165 ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n", 02166 reliable ? "Reliably " : "", sip_nat_mode(p), 02167 ast_inet_ntoa(dst->sin_addr), 02168 ntohs(dst->sin_port), req->data); 02169 } 02170 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 02171 struct sip_request tmp; 02172 parse_copy(&tmp, req); 02173 append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data, get_header(&tmp, "CSeq"), 02174 (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? tmp.rlPart2 : sip_methods[tmp.method].text); 02175 } 02176 res = (reliable) ? 02177 __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) : 02178 __sip_xmit(p, req->data, req->len); 02179 if (res > 0) 02180 return 0; 02181 return res; 02182 }
| static int set_address_from_contact | ( | struct sip_pvt * | pvt | ) | [static] |
Change the other partys IP address based on given contact.
Definition at line 7698 of file chan_sip.c.
References ahp, ast_gethostbyname(), ast_log(), ast_strdupa, ast_test_flag, sip_pvt::flags, hp, LOG_NOTICE, LOG_WARNING, sip_pvt::recv, sip_pvt::sa, SIP_NAT_ROUTE, STANDARD_SIP_PORT, and strsep().
Referenced by handle_response_invite().
07699 { 07700 struct hostent *hp; 07701 struct ast_hostent ahp; 07702 int port; 07703 char *c, *host, *pt; 07704 char *contact; 07705 07706 07707 if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) { 07708 /* NAT: Don't trust the contact field. Just use what they came to us 07709 with. */ 07710 pvt->sa = pvt->recv; 07711 return 0; 07712 } 07713 07714 07715 /* Work on a copy */ 07716 contact = ast_strdupa(pvt->fullcontact); 07717 07718 /* XXX this code is repeated all over */ 07719 /* Make sure it's a SIP URL */ 07720 if (strncasecmp(contact, "sip:", 4)) { 07721 ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 07722 } else 07723 contact += 4; 07724 07725 /* Ditch arguments */ 07726 /* XXX this code is replicated also shortly below */ 07727 contact = strsep(&contact, ";"); /* trim ; and beyond */ 07728 07729 /* Grab host */ 07730 host = strchr(contact, '@'); 07731 if (!host) { /* No username part */ 07732 host = contact; 07733 c = NULL; 07734 } else { 07735 *host++ = '\0'; 07736 } 07737 pt = strchr(host, ':'); 07738 if (pt) { 07739 *pt++ = '\0'; 07740 port = atoi(pt); 07741 } else 07742 port = STANDARD_SIP_PORT; 07743 07744 /* XXX This could block for a long time XXX */ 07745 /* We should only do this if it's a name, not an IP */ 07746 hp = ast_gethostbyname(host, &ahp); 07747 if (!hp) { 07748 ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host); 07749 return -1; 07750 } 07751 pvt->sa.sin_family = AF_INET; 07752 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 07753 pvt->sa.sin_port = htons(port); 07754 07755 return 0; 07756 }
| static void set_destination | ( | struct sip_pvt * | p, | |
| char * | uri | |||
| ) | [static] |
Set destination from SIP URI.
Definition at line 5494 of file chan_sip.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_verbose(), debug, hostname, hp, LOG_WARNING, sip_pvt::sa, sip_debug_test_pvt(), and STANDARD_SIP_PORT.
Referenced by reqprep().
05495 { 05496 char *h, *maddr, hostname[256]; 05497 int port, hn; 05498 struct hostent *hp; 05499 struct ast_hostent ahp; 05500 int debug=sip_debug_test_pvt(p); 05501 05502 /* Parse uri to h (host) and port - uri is already just the part inside the <> */ 05503 /* general form we are expecting is sip[s]:username[:password]@host[:port][;...] */ 05504 05505 if (debug) 05506 ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri); 05507 05508 /* Find and parse hostname */ 05509 h = strchr(uri, '@'); 05510 if (h) 05511 ++h; 05512 else { 05513 h = uri; 05514 if (strncmp(h, "sip:", 4) == 0) 05515 h += 4; 05516 else if (strncmp(h, "sips:", 5) == 0) 05517 h += 5; 05518 } 05519 hn = strcspn(h, ":;>") + 1; 05520 if (hn > sizeof(hostname)) 05521 hn = sizeof(hostname); 05522 ast_copy_string(hostname, h, hn); 05523 /* XXX bug here if string has been trimmed to sizeof(hostname) */ 05524 h += hn - 1; 05525 05526 /* Is "port" present? if not default to STANDARD_SIP_PORT */ 05527 if (*h == ':') { 05528 /* Parse port */ 05529 ++h; 05530 port = strtol(h, &h, 10); 05531 } 05532 else 05533 port = STANDARD_SIP_PORT; 05534 05535 /* Got the hostname:port - but maybe there's a "maddr=" to override address? */ 05536 maddr = strstr(h, "maddr="); 05537 if (maddr) { 05538 maddr += 6; 05539 hn = strspn(maddr, "0123456789.") + 1; 05540 if (hn > sizeof(hostname)) 05541 hn = sizeof(hostname); 05542 ast_copy_string(hostname, maddr, hn); 05543 } 05544 05545 hp = ast_gethostbyname(hostname, &ahp); 05546 if (hp == NULL) { 05547 ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname); 05548 return; 05549 } 05550 p->sa.sin_family = AF_INET; 05551 memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr)); 05552 p->sa.sin_port = htons(port); 05553 if (debug) 05554 ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port); 05555 }
| static void set_peer_defaults | ( | struct sip_peer * | peer | ) | [static] |
Set peer defaults before configuring specific configurations.
Definition at line 15882 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().
15883 { 15884 if (peer->expire == 0) { 15885 /* Don't reset expire or port time during reload 15886 if we have an active registration 15887 */ 15888 peer->expire = -1; 15889 peer->pokeexpire = -1; 15890 peer->addr.sin_port = htons(STANDARD_SIP_PORT); 15891 } 15892 ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 15893 ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 15894 strcpy(peer->context, default_context); 15895 strcpy(peer->subscribecontext, default_subscribecontext); 15896 strcpy(peer->language, default_language); 15897 strcpy(peer->mohinterpret, default_mohinterpret); 15898 strcpy(peer->mohsuggest, default_mohsuggest); 15899 peer->addr.sin_family = AF_INET; 15900 peer->defaddr.sin_family = AF_INET; 15901 peer->capability = global_capability; 15902 peer->maxcallbitrate = default_maxcallbitrate; 15903 peer->rtptimeout = global_rtptimeout; 15904 peer->rtpholdtimeout = global_rtpholdtimeout; 15905 peer->rtpkeepalive = global_rtpkeepalive; 15906 peer->allowtransfer = global_allowtransfer; 15907 peer->autoframing = global_autoframing; 15908 strcpy(peer->vmexten, default_vmexten); 15909 peer->secret[0] = '\0'; 15910 peer->md5secret[0] = '\0'; 15911 peer->cid_num[0] = '\0'; 15912 peer->cid_name[0] = '\0'; 15913 peer->fromdomain[0] = '\0'; 15914 peer->fromuser[0] = '\0'; 15915 peer->regexten[0] = '\0'; 15916 peer->mailbox[0] = '\0'; 15917 peer->callgroup = 0; 15918 peer->pickupgroup = 0; 15919 peer->maxms = default_qualify; 15920 peer->prefs = default_prefs; 15921 }
| static int sip_addheader | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Add a SIP header to an outbound INVITE.
Definition at line 17075 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), ast_strlen_zero(), FALSE, inbuf(), LOG_DEBUG, LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), sipdebug, and TRUE.
Referenced by load_module().
17076 { 17077 int no = 0; 17078 int ok = FALSE; 17079 char varbuf[30]; 17080 char *inbuf = (char *) data; 17081 17082 if (ast_strlen_zero(inbuf)) { 17083 ast_log(LOG_WARNING, "This application requires the argument: Header\n"); 17084 return 0; 17085 } 17086 ast_channel_lock(chan); 17087 17088 /* Check for headers */ 17089 while (!ok && no <= 50) { 17090 no++; 17091 snprintf(varbuf, sizeof(varbuf), "_SIPADDHEADER%.2d", no); 17092 17093 /* Compare without the leading underscore */ 17094 if( (pbx_builtin_getvar_helper(chan, (const char *) varbuf + 1) == (const char *) NULL) ) 17095 ok = TRUE; 17096 } 17097 if (ok) { 17098 pbx_builtin_setvar_helper (chan, varbuf, inbuf); 17099 if (sipdebug) 17100 ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", inbuf, varbuf); 17101 } else { 17102 ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n"); 17103 } 17104 ast_channel_unlock(chan); 17105 return 0; 17106 }
| static int sip_addrcmp | ( | char * | name, | |
| struct sockaddr_in * | sin | |||
| ) | [static] |
Support routine for find_peer.
Definition at line 2470 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, inaddrcmp(), and SIP_INSECURE_PORT.
Referenced by find_peer().
02471 { 02472 /* We know name is the first field, so we can cast */ 02473 struct sip_peer *p = (struct sip_peer *) name; 02474 return !(!inaddrcmp(&p->addr, sin) || 02475 (ast_test_flag(&p->flags[0], SIP_INSECURE_PORT) && 02476 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr))); 02477 }
| 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 4202 of file chan_sip.c.
References __ourip, ast_calloc, ast_copy_flags, ast_log(), ast_mutex_destroy(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), AST_RTP_DTMF, ast_rtp_new_with_bindaddr(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_settos(), ast_set2_flag, ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_set, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_new_with_bindaddr(), ast_udptl_settos(), ast_variables_destroy(), bindaddr, build_callid_pvt(), build_via(), context, default_prefs, do_setnat(), free, global_flags, global_t38_capability, iflist, INITIAL_CSEQ, io, LOG_DEBUG, LOG_WARNING, make_our_tag(), mohinterpret, mohsuggest, NONE, option_debug, sched, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, SIP_OPTIONS, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_REGISTER, T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF, T38FAX_UDP_EC_FEC, T38FAX_UDP_EC_NONE, T38FAX_UDP_EC_REDUNDANCY, text, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.
Referenced by sip_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
04204 { 04205 struct sip_pvt *p; 04206 04207 if (!(p = ast_calloc(1, sizeof(*p)))) 04208 return NULL; 04209 04210 if (ast_string_field_init(p, 512)) { 04211 free(p); 04212 return NULL; 04213 } 04214 04215 ast_mutex_init(&p->lock); 04216 04217 p->method = intended_method; 04218 p->initid = -1; 04219 p->autokillid = -1; 04220 p->subscribed = NONE; 04221 p->stateid = -1; 04222 p->prefs = default_prefs; /* Set default codecs for this call */ 04223 04224 if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */ 04225 p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ 04226 04227 if (sin) { 04228 p->sa = *sin; 04229 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 04230 p->ourip = __ourip; 04231 } else 04232 p->ourip = __ourip; 04233 04234 /* Copy global flags to this PVT at setup. */ 04235 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY); 04236 ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY); 04237 04238 ast_set2_flag(&p->flags[0], !recordhistory, SIP_NO_HISTORY); 04239 04240 p->branch = ast_random(); 04241 make_our_tag(p->tag, sizeof(p->tag)); 04242 p->ocseq = INITIAL_CSEQ; 04243 04244 if (sip_methods[intended_method].need_rtp) { 04245 p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04246 /* If the global videosupport flag is on, we always create a RTP interface for video */ 04247 if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT)) 04248 p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 04249 if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) 04250 p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr); 04251 if (!p->rtp || (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) { 04252 ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", 04253 ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno)); 04254 ast_mutex_destroy(&p->lock); 04255 if (p->chanvars) { 04256 ast_variables_destroy(p->chanvars); 04257 p->chanvars = NULL; 04258 } 04259 free(p); 04260 return NULL; 04261 } 04262 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 04263 ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE)); 04264 ast_rtp_settos(p->rtp, global_tos_audio); 04265 ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout); 04266 ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout); 04267 ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive); 04268 if (p->vrtp) { 04269 ast_rtp_settos(p->vrtp, global_tos_video); 04270 ast_rtp_setdtmf(p->vrtp, 0); 04271 ast_rtp_setdtmfcompensate(p->vrtp, 0); 04272 ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout); 04273 ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout); 04274 ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive); 04275 } 04276 if (p->udptl) 04277 ast_udptl_settos(p->udptl, global_tos_audio); 04278 p->maxcallbitrate = default_maxcallbitrate; 04279 } 04280 04281 if (useglobal_nat && sin) { 04282 /* Setup NAT structure according to global settings if we have an address */ 04283 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 04284 p->recv = *sin; 04285 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 04286 } 04287 04288 if (p->method != SIP_REGISTER) 04289 ast_string_field_set(p, fromdomain, default_fromdomain); 04290 build_via(p); 04291 if (!callid) 04292 build_callid_pvt(p); 04293 else 04294 ast_string_field_set(p, callid, callid); 04295 /* Assign default music on hold class */ 04296 ast_string_field_set(p, mohinterpret, default_mohinterpret); 04297 ast_string_field_set(p, mohsuggest, default_mohsuggest); 04298 p->capability = global_capability; 04299 p->allowtransfer = global_allowtransfer; 04300 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) || 04301 (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO)) 04302 p->noncodeccapability |= AST_RTP_DTMF; 04303 if (p->udptl) { 04304 p->t38.capability = global_t38_capability; 04305 if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY) 04306 p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY; 04307 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC) 04308 p->t38.capability |= T38FAX_UDP_EC_FEC; 04309 else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE) 04310 p->t38.capability |= T38FAX_UDP_EC_NONE; 04311 p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF; 04312 p->t38.jointcapability = p->t38.capability; 04313 } 04314 ast_string_field_set(p, context, default_context); 04315 04316 /* Add to active dialog list */ 04317 ast_mutex_lock(&iflock); 04318 p->next = iflist; 04319 iflist = p; 04320 ast_mutex_unlock(&iflock); 04321 if (option_debug) 04322 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"); 04323 return p; 04324 }
| static void sip_alreadygone | ( | struct sip_pvt * | dialog | ) | [static] |
Definition at line 1631 of file chan_sip.c.
References ast_log(), ast_set_flag, sip_pvt::flags, LOG_DEBUG, option_debug, and SIP_ALREADYGONE.
Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), retrans_pkt(), and sip_indicate().
01632 { 01633 if (option_debug > 2) 01634 ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid); 01635 ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE); 01636 }
| 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 3453 of file chan_sip.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_UP, sip_pvt::lock, LOG_DEBUG, option_debug, T38_ENABLED, T38_PEER_DIRECT, ast_channel::tech_pvt, transmit_response_with_sdp(), transmit_response_with_t38_sdp(), try_suggested_sip_codec(), and XMIT_CRITICAL.
03454 { 03455 int res = 0; 03456 struct sip_pvt *p = ast->tech_pvt; 03457 03458 ast_mutex_lock(&p->lock); 03459 if (ast->_state != AST_STATE_UP) { 03460 try_suggested_sip_codec(p); 03461 03462 ast_setstate(ast, AST_STATE_UP); 03463 if (option_debug) 03464 ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name); 03465 if (p->t38.state == T38_PEER_DIRECT) { 03466 p->t38.state = T38_ENABLED; 03467 if (option_debug > 1) 03468 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 03469 res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03470 } else 03471 res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 03472 } 03473 ast_mutex_unlock(&p->lock); 03474 return res; 03475 }
| 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 2771 of file chan_sip.c.
References ast_channel::_state, sip_invite_param::addsipheaders, AST_FORMAT_AUDIO_MASK, AST_LIST_TRAVERSE, ast_log(), ast_sched_add(), ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_string_field_set, ast_translate_available_formats(), ast_var_name(), ast_var_value(), auto_congest(), sip_pvt::callingpres, t38properties::capability, sip_pvt::capability, ast_channel::cid, cid_name, ast_callerid::cid_pres, sip_invite_param::distinctive_ring, sip_pvt::flags, INC_CALL_RINGING, sip_pvt::initid, INV_CALLING, sip_pvt::invitestate, t38properties::jointcapability, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, LOG_DEBUG, LOG_WARNING, sip_pvt::maxtime, sip_pvt::noncodeccapability, option_debug, sip_pvt::options, sip_pvt::prefcodec, sip_invite_param::replaces, sched, SIP_INVITE, SIP_OUTGOING, SIP_TRANS_TIMEOUT, sipdebug, t38properties::state, sip_pvt::t38, T38_LOCAL_DIRECT, ast_channel::tech_pvt, sip_invite_param::transfer, transmit_invite(), update_call_counter(), sip_invite_param::uri_options, ast_channel::varshead, and sip_invite_param::vxml_url.
02772 { 02773 int res; 02774 struct sip_pvt *p; 02775 struct varshead *headp; 02776 struct ast_var_t *current; 02777 const char *referer = NULL; /* SIP refererer */ 02778 02779 p = ast->tech_pvt; 02780 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 02781 ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name); 02782 return -1; 02783 } 02784 02785 /* Check whether there is vxml_url, distinctive ring variables */ 02786 headp=&ast->varshead; 02787 AST_LIST_TRAVERSE(headp,current,entries) { 02788 /* Check whether there is a VXML_URL variable */ 02789 if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) { 02790 p->options->vxml_url = ast_var_value(current); 02791 } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) { 02792 p->options->uri_options = ast_var_value(current); 02793 } else if (!p->options->distinctive_ring && !strcasecmp(ast_var_name(current), "ALERT_INFO")) { 02794 /* Check whether there is a ALERT_INFO variable */ 02795 p->options->distinctive_ring = ast_var_value(current); 02796 } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 02797 /* Check whether there is a variable with a name starting with SIPADDHEADER */ 02798 p->options->addsipheaders = 1; 02799 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) { 02800 /* This is a transfered call */ 02801 p->options->transfer = 1; 02802 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) { 02803 /* This is the referer */ 02804 referer = ast_var_value(current); 02805 } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) { 02806 /* We're replacing a call. */ 02807 p->options->replaces = ast_var_value(current); 02808 } else if (!strcasecmp(ast_var_name(current), "T38CALL")) { 02809 p->t38.state = T38_LOCAL_DIRECT; 02810 if (option_debug) 02811 ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); 02812 } 02813 02814 } 02815 02816 res = 0; 02817 ast_set_flag(&p->flags[0], SIP_OUTGOING); 02818 02819 if (p->options->transfer) { 02820 char buf[BUFSIZ/2]; 02821 02822 if (referer) { 02823 if (sipdebug && option_debug > 2) 02824 ast_log(LOG_DEBUG, "Call for %s transfered by %s\n", p->username, referer); 02825 snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer); 02826 } else 02827 snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name); 02828 ast_string_field_set(p, cid_name, buf); 02829 } 02830 if (option_debug) 02831 ast_log(LOG_DEBUG, "Outgoing Call for %s\n", p->username); 02832 02833 res = update_call_counter(p, INC_CALL_RINGING); 02834 if ( res != -1 ) { 02835 p->callingpres = ast->cid.cid_pres; 02836 p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec); 02837 p->jointnoncodeccapability = p->noncodeccapability; 02838 02839 /* If there are no audio formats left to offer, punt */ 02840 if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) { 02841 ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username); 02842 res = -1; 02843 } else { 02844 p->t38.jointcapability = p->t38.capability; 02845 if (option_debug > 1) 02846 ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability); 02847 transmit_invite(p, SIP_INVITE, 1, 2); 02848 p->invitestate = INV_CALLING; 02849 02850 /* Initialize auto-congest time */ 02851 p->initid = ast_sched_add(sched, p->maxtime ? (p->maxtime * 4) : SIP_TRANS_TIMEOUT, auto_congest, p); 02852 } 02853 } 02854 return res; 02855 }
| static void sip_cancel_destroy | ( | struct sip_pvt * | p | ) | [static] |
Cancel destruction of SIP dialog.
Definition at line 2045 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().
02046 { 02047 if (p->autokillid > -1) { 02048 ast_sched_del(sched, p->autokillid); 02049 append_history(p, "CancelDestroy", ""); 02050 p->autokillid = -1; 02051 } 02052 }
| static int sip_debug_test_addr | ( | const struct sockaddr_in * | addr | ) | [inline, static] |
See if we pass debug IP filter.
Definition at line 1713 of file chan_sip.c.
References sipdebug.
Referenced by check_user_full(), sip_debug_test_pvt(), and sipsock_read().
01714 { 01715 if (!sipdebug) 01716 return 0; 01717 if (debugaddr.sin_addr.s_addr) { 01718 if (((ntohs(debugaddr.sin_port) != 0) 01719 && (debugaddr.sin_port != addr->sin_port)) 01720 || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 01721 return 0; 01722 } 01723 return 1; 01724 }
| static int sip_debug_test_pvt | ( | struct sip_pvt * | p | ) | [inline, static] |
Test PVT for debugging output.
Definition at line 1739 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().
01740 { 01741 if (!sipdebug) 01742 return 0; 01743 return sip_debug_test_addr(sip_real_dst(p)); 01744 }
| static void sip_destroy | ( | struct sip_pvt * | p | ) | [static] |
Destroy SIP call structure.
Definition at line 3106 of file chan_sip.c.
References __sip_destroy(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_DEBUG, and option_debug.
Referenced by __sip_autodestruct(), handle_request_subscribe(), sip_destroy_peer(), sip_do_reload(), sip_notify(), sip_poke_noanswer(), sip_poke_peer(), sip_registry_destroy(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().
03107 { 03108 ast_mutex_lock(&iflock); 03109 if (option_debug > 2) 03110 ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", p->callid); 03111 __sip_destroy(p, 1); 03112 ast_mutex_unlock(&iflock); 03113 }
| static void sip_destroy_peer | ( | struct sip_peer * | peer | ) | [static] |
Destroy peer object from memory.
Definition at line 2357 of file chan_sip.c.
References ast_free_ha(), ast_log(), ast_sched_del(), ast_test_flag, ast_variables_destroy(), sip_peer::auth, sip_peer::call, sip_peer::chanvars, clear_realm_authentication(), sip_peer::expire, FALSE, sip_peer::flags, free, sip_peer::ha, LOG_DEBUG, sip_peer::mwipvt, option_debug, sip_peer::pokeexpire, register_peer_exten(), sched, sip_destroy(), SIP_PAGE2_SELFDESTRUCT, and SIP_REALTIME.
Referenced by __sip_autodestruct(), _sip_show_peer(), build_peer(), check_user_full(), create_addr(), expire_register(), function_sippeer(), handle_request_subscribe(), register_verify(), sip_devicestate(), sip_do_debug_peer(), sip_prune_realtime(), unload_module(), and update_call_counter().
02358 { 02359 if (option_debug > 2) 02360 ast_log(LOG_DEBUG, "Destroying SIP peer %s\n", peer->name); 02361 02362 /* Delete it, it needs to disappear */ 02363 if (peer->call) 02364 sip_destroy(peer->call); 02365 02366 if (peer->mwipvt) /* We have an active subscription, delete it */ 02367 sip_destroy(peer->mwipvt); 02368 02369 if (peer->chanvars) { 02370 ast_variables_destroy(peer->chanvars); 02371 peer->chanvars = NULL; 02372 } 02373 if (peer->expire > -1) 02374 ast_sched_del(sched, peer->expire); 02375 02376 if (peer->pokeexpire > -1) 02377 ast_sched_del(sched, peer->pokeexpire); 02378 register_peer_exten(peer, FALSE); 02379 ast_free_ha(peer->ha); 02380 if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT)) 02381 apeerobjs--; 02382 else if (ast_test_flag(&peer->flags[0], SIP_REALTIME)) 02383 rpeerobjs--; 02384 else 02385 speerobjs--; 02386 clear_realm_authentication(peer->auth); 02387 peer->auth = NULL; 02388 free(peer); 02389 }
| static void sip_destroy_user | ( | struct sip_user * | user | ) | [static] |
Remove user object from in-memory storage.
Definition at line 2498 of file chan_sip.c.
References ast_free_ha(), ast_log(), ast_test_flag, ast_variables_destroy(), sip_user::chanvars, sip_user::flags, free, sip_user::ha, LOG_DEBUG, option_debug, and SIP_REALTIME.
Referenced by check_user_full(), sip_show_user(), unload_module(), and update_call_counter().
02499 { 02500 if (option_debug > 2) 02501 ast_log(LOG_DEBUG, "Destroying user object from memory: %s\n", user->name); 02502 ast_free_ha(user->ha); 02503 if (user->chanvars) { 02504 ast_variables_destroy(user->chanvars); 02505 user->chanvars = NULL; 02506 } 02507 if (ast_test_flag(&user->flags[0], SIP_REALTIME)) 02508 ruserobjs--; 02509 else 02510 suserobjs--; 02511 free(user); 02512 }
| 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 15320 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().
15321 { 15322 char *host; 15323 char *tmp; 15324 15325 struct hostent *hp; 15326 struct ast_hostent ahp; 15327 struct sip_peer *p; 15328 15329 int res = AST_DEVICE_INVALID; 15330 15331 /* make sure data is not null. Maybe unnecessary, but better be safe */ 15332 host = ast_strdupa(data ? data : ""); 15333 if ((tmp = strchr(host, '@'))) 15334 host = tmp + 1; 15335 15336 if (option_debug > 2) 15337 ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host); 15338 15339 if ((p = find_peer(host, NULL, 1))) { 15340 if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) { 15341 /* we have an address for the peer */ 15342 15343 /* Check status in this order 15344 - Hold 15345 - Ringing 15346 - Busy (enforced only by call limit) 15347 - Inuse (we have a call) 15348 - Unreachable (qualify) 15349 If we don't find any of these state, report AST_DEVICE_NOT_INUSE 15350 for registered devices */ 15351 15352 if (p->onHold) 15353 /* First check for hold or ring states */ 15354 res = AST_DEVICE_ONHOLD; 15355 else if (p->inRinging) { 15356 if (p->inRinging == p->inUse) 15357 res = AST_DEVICE_RINGING; 15358 else 15359 res = AST_DEVICE_RINGINUSE; 15360 } else if (p->call_limit && (p->inUse == p->call_limit)) 15361 /* check call limit */ 15362 res = AST_DEVICE_BUSY; 15363 else if (p->call_limit && p->inUse) 15364 /* Not busy, but we do have a call */ 15365 res = AST_DEVICE_INUSE; 15366 else if (p->maxms && (p->lastms > p->maxms)) 15367 /* We don't have a call. Are we reachable at all? Requires qualify= */ 15368 res = AST_DEVICE_UNAVAILABLE; 15369 else /* Default reply if we're registered and have no other data */ 15370 res = AST_DEVICE_NOT_INUSE; 15371 } else { 15372 /* there is no address, it's unavailable */ 15373 res = AST_DEVICE_UNAVAILABLE; 15374 } 15375 ASTOBJ_UNREF(p,sip_destroy_peer); 15376 } else { 15377 hp = ast_gethostbyname(host, &ahp); 15378 if (hp) 15379 res = AST_DEVICE_UNKNOWN; 15380 } 15381 15382 return res; 15383 }
| static int sip_do_debug | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Turn on SIP debugging (CLI command).
Definition at line 10926 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.
10927 { 10928 int oldsipdebug = sipdebug_console; 10929 if (argc != 3) { 10930 if (argc != 5) 10931 return RESULT_SHOWUSAGE; 10932 else if (strcmp(argv[3], "ip") == 0) 10933 return sip_do_debug_ip(fd, argc, argv); 10934 else if (strcmp(argv[3], "peer") == 0) 10935 return sip_do_debug_peer(fd, argc, argv); 10936 else 10937 return RESULT_SHOWUSAGE; 10938 } 10939 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 10940 memset(&debugaddr, 0, sizeof(debugaddr)); 10941 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 10942 return RESULT_SUCCESS; 10943 }
| static int sip_do_debug_deprecated | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 10945 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.
10946 { 10947 int oldsipdebug = sipdebug_console; 10948 char *newargv[6] = { "sip", "set", "debug", NULL }; 10949 if (argc != 2) { 10950 if (argc != 4) 10951 return RESULT_SHOWUSAGE; 10952 else if (strcmp(argv[2], "ip") == 0) { 10953 newargv[3] = argv[2]; 10954 newargv[4] = argv[3]; 10955 return sip_do_debug_ip(fd, argc + 1, newargv); 10956 } else if (strcmp(argv[2], "peer") == 0) { 10957 newargv[3] = argv[2]; 10958 newargv[4] = argv[3]; 10959 return sip_do_debug_peer(fd, argc + 1, newargv); 10960 } else 10961 return RESULT_SHOWUSAGE; 10962 } 10963 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 10964 memset(&debugaddr, 0, sizeof(debugaddr)); 10965 ast_cli(fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : ""); 10966 return RESULT_SUCCESS; 10967 }
| static int sip_do_debug_ip | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Enable SIP Debugging in CLI.
Definition at line 10872 of file chan_sip.c.
References ahp, ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), ast_set_flag, debugaddr, global_flags, hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, SIP_PAGE2_DEBUG_CONSOLE, and strsep().
Referenced by sip_do_debug(), and sip_do_debug_deprecated().
10873 { 10874 struct hostent *hp; 10875 struct ast_hostent ahp; 10876 int port = 0; 10877 char *p, *arg; 10878 10879 /* sip set debug ip <ip> */ 10880 if (argc != 5) 10881 return RESULT_SHOWUSAGE; 10882 p = arg = argv[4]; 10883 strsep(&p, ":"); 10884 if (p) 10885 port = atoi(p); 10886 hp = ast_gethostbyname(arg, &ahp); 10887 if (hp == NULL) 10888 return RESULT_SHOWUSAGE; 10889 10890 debugaddr.sin_family = AF_INET; 10891 memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr)); 10892 debugaddr.sin_port = htons(port); 10893 if (port == 0) 10894 ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr)); 10895 else 10896 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port); 10897 10898 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 10899 10900 return RESULT_SUCCESS; 10901 }
| 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 10904 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().
10905 { 10906 struct sip_peer *peer; 10907 if (argc != 5) 10908 return RESULT_SHOWUSAGE; 10909 peer = find_peer(argv[4], NULL, 1); 10910 if (peer) { 10911 if (peer->addr.sin_addr.s_addr) { 10912 debugaddr.sin_family = AF_INET; 10913 debugaddr.sin_addr = peer->addr.sin_addr; 10914 debugaddr.sin_port = peer->addr.sin_port; 10915 ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 10916 ast_set_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 10917 } else 10918 ast_cli(fd, "Unable to get IP address of peer '%s'\n", argv[4]); 10919 ASTOBJ_UNREF(peer,sip_destroy_peer); 10920 } else 10921 ast_cli(fd, "No such peer '%s'\n", argv[4]); 10922 return RESULT_SUCCESS; 10923 }
| static int sip_do_history | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Enable SIP History logging (CLI).
Definition at line 11045 of file chan_sip.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and TRUE.
11046 { 11047 if (argc != 2) { 11048 return RESULT_SHOWUSAGE; 11049 } 11050 recordhistory = TRUE; 11051 ast_cli(fd, "SIP History Recording Enabled (use 'sip show history')\n"); 11052 return RESULT_SUCCESS; 11053 }
| static int sip_do_reload | ( | enum channelreloadreason | reason | ) | [static] |
Reload module.
Definition at line 17216 of file chan_sip.c.
References ast_log(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, authl, clear_realm_authentication(), clear_sip_domains(), LOG_DEBUG, regl, and sip_destroy().
Referenced by do_monitor().
17217 { 17218 if (option_debug > 3) 17219 ast_log(LOG_DEBUG, "--------------- SIP reload started\n"); 17220 17221 clear_realm_authentication(authl); 17222 clear_sip_domains(); 17223 authl = NULL; 17224 17225 /* First, destroy all outstanding registry calls */ 17226 /* This is needed, since otherwise active registry entries will not be destroyed */ 17227 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17228 ASTOBJ_RDLOCK(iterator); 17229 if (iterator->call) { 17230 if (option_debug > 2) 17231 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname); 17232 /* This will also remove references to the registry */ 17233 sip_destroy(iterator->call); 17234 } 17235 ASTOBJ_UNLOCK(iterator); 17236 17237 } while(0)); 17238 17239 /* Then, actually destroy users and registry */ 17240 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 17241 if (option_debug > 3) 17242 ast_log(LOG_DEBUG, "--------------- Done destroying user list\n"); 17243 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 17244 if (option_debug > 3) 17245 ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n"); 17246 ASTOBJ_CONTAINER_MARKALL(&peerl); 17247 reload_config(reason); 17248 17249 /* Prune peers who still are supposed to be deleted */ 17250 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 17251 if (option_debug > 3) 17252 ast_log(LOG_DEBUG, "--------------- Done destroying pruned peers\n"); 17253 17254 /* Send qualify (OPTIONS) to all peers */ 17255 sip_poke_all_peers(); 17256 17257 /* Register with all services */ 17258 sip_send_all_registers(); 17259 17260 if (option_debug > 3) 17261 ast_log(LOG_DEBUG, "--------------- SIP reload done\n"); 17262 17263 return 0; 17264 }
| static int sip_dtmfmode | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Set the DTMFmode for an outbound SIP call (application).
Definition at line 17020 of file chan_sip.c.
References ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_dsp_free(), ast_dsp_new(), ast_dsp_set_features(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_DTMF, ast_rtp_setdtmf(), ast_set_flag, ast_test_flag, DSP_FEATURE_DTMF_DETECT, sip_pvt::flags, sip_pvt::jointnoncodeccapability, sip_pvt::lock, LOG_WARNING, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, and sip_pvt::vad.
Referenced by load_module().
17021 { 17022 struct sip_pvt *p; 17023 char *mode; 17024 if (data) 17025 mode = (char *)data; 17026 else { 17027 ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n"); 17028 return 0; 17029 } 17030 ast_channel_lock(chan); 17031 if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) { 17032 ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n"); 17033 ast_channel_unlock(chan); 17034 return 0; 17035 } 17036 p = chan->tech_pvt; 17037 if (!p) { 17038 ast_channel_unlock(chan); 17039 return 0; 17040 } 17041 ast_mutex_lock(&p->lock); 17042 if (!strcasecmp(mode,"info")) { 17043 ast_clear_flag(&p->flags[0], SIP_DTMF); 17044 ast_set_flag(&p->flags[0], SIP_DTMF_INFO); 17045 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 17046 } else if (!strcasecmp(mode,"rfc2833")) { 17047 ast_clear_flag(&p->flags[0], SIP_DTMF); 17048 ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833); 17049 p->jointnoncodeccapability |= AST_RTP_DTMF; 17050 } else if (!strcasecmp(mode,"inband")) { 17051 ast_clear_flag(&p->flags[0], SIP_DTMF); 17052 ast_set_flag(&p->flags[0], SIP_DTMF_INBAND); 17053 p->jointnoncodeccapability &= ~AST_RTP_DTMF; 17054 } else 17055 ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n",mode); 17056 if (p->rtp) 17057 ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833); 17058 if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 17059 if (!p->vad) { 17060 p->vad = ast_dsp_new(); 17061 ast_dsp_set_features(p->vad, DSP_FEATURE_DTMF_DETECT); 17062 } 17063 } else { 17064 if (p->vad) { 17065 ast_dsp_free(p->vad); 17066 p->vad = NULL; 17067 } 17068 } 17069 ast_mutex_unlock(&p->lock); 17070 ast_channel_unlock(chan); 17071 return 0; 17072 }
| 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 10742 of file chan_sip.c.
References AST_LIST_TRAVERSE, ast_log(), sip_pvt::history, LOG_DEBUG, LOG_NOTICE, option_debug, sipdebug, and sip_pvt::subscribed.
Referenced by __sip_destroy().
10743 { 10744 int x = 0; 10745 struct sip_history *hist; 10746 static int errmsg = 0; 10747 10748 if (!dialog) 10749 return; 10750 10751 if (!option_debug && !sipdebug) { 10752 if (!errmsg) { 10753 ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n"); 10754 errmsg = 1; 10755 } 10756 return; 10757 } 10758 10759 ast_log(LOG_DEBUG, "\n---------- SIP HISTORY for '%s' \n", dialog->callid); 10760 if (dialog->subscribed) 10761 ast_log(LOG_DEBUG, " * Subscription\n"); 10762 else 10763 ast_log(LOG_DEBUG, " * SIP Call\n"); 10764 if (dialog->history) 10765 AST_LIST_TRAVERSE(dialog->history, hist, list) 10766 ast_log(LOG_DEBUG, " %-3.3d. %s\n", ++x, hist->event); 10767 if (!x) 10768 ast_log(LOG_DEBUG, "Call '%s' has no history\n", dialog->callid); 10769 ast_log(LOG_DEBUG, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid); 10770 }
| 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 3557 of file chan_sip.c.
References append_history, AST_FLAG_ZOMBIE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, option_debug, sip_pvt::owner, and ast_channel::tech_pvt.
03558 { 03559 int ret = -1; 03560 struct sip_pvt *p; 03561 03562 if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE) && option_debug) 03563 ast_log(LOG_DEBUG, "New channel is zombie\n"); 03564 if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE) && option_debug) 03565 ast_log(LOG_DEBUG, "Old channel is zombie\n"); 03566 03567 if (!newchan || !newchan->tech_pvt) { 03568 if (!newchan) 03569 ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name); 03570 else 03571 ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name); 03572 return -1; 03573 } 03574 p = newchan->tech_pvt; 03575 03576 if (!p) { 03577 ast_log(LOG_WARNING, "No pvt after masquerade. Strange things may happen\n"); 03578 return -1; 03579 } 03580 03581 ast_mutex_lock(&p->lock); 03582 append_history(p, "Masq", "Old channel: %s\n", oldchan->name); 03583 append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name); 03584 if (p->owner != oldchan) 03585 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner); 03586 else { 03587 p->owner = newchan; 03588 ret = 0; 03589 } 03590 if (option_debug > 2) 03591 ast_log(LOG_DEBUG, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name); 03592 03593 ast_mutex_unlock(&p->lock); 03594 return ret; 03595 }
| static int sip_get_codec | ( | struct ast_channel * | chan | ) | [static] |
Return SIP UA's codec (part of the RTP interface).
Definition at line 17165 of file chan_sip.c.
References sip_pvt::capability, sip_pvt::peercapability, and ast_channel::tech_pvt.
17166 { 17167 struct sip_pvt *p = chan->tech_pvt; 17168 return p->peercapability ? p->peercapability : p->capability; 17169 }
| 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 16880 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.
16881 { 16882 struct sip_pvt *p = NULL; 16883 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 16884 16885 if (!(p = chan->tech_pvt)) 16886 return AST_RTP_GET_FAILED; 16887 16888 ast_mutex_lock(&p->lock); 16889 if (!(p->rtp)) { 16890 ast_mutex_unlock(&p->lock); 16891 return AST_RTP_GET_FAILED; 16892 } 16893 16894 *rtp = p->rtp; 16895 16896 if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) 16897 res = AST_RTP_TRY_PARTIAL; 16898 else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 16899 res = AST_RTP_TRY_NATIVE; 16900 else if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) 16901 res = AST_RTP_GET_FAILED; 16902 16903 ast_mutex_unlock(&p->lock); 16904 16905 return res; 16906 }
| static struct ast_udptl * sip_get_udptl_peer | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 16745 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.
16746 { 16747 struct sip_pvt *p; 16748 struct ast_udptl *udptl = NULL; 16749 16750 p = chan->tech_pvt; 16751 if (!p) 16752 return NULL; 16753 16754 ast_mutex_lock(&p->lock); 16755 if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 16756 udptl = p->udptl; 16757 ast_mutex_unlock(&p->lock); 16758 return udptl; 16759 }
| 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 16909 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.
16910 { 16911 struct sip_pvt *p = NULL; 16912 enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL; 16913 16914 if (!(p = chan->tech_pvt)) 16915 return AST_RTP_GET_FAILED; 16916 16917 ast_mutex_lock(&p->lock); 16918 if (!(p->vrtp)) { 16919 ast_mutex_unlock(&p->lock); 16920 return AST_RTP_GET_FAILED; 16921 } 16922 16923 *rtp = p->vrtp; 16924 16925 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) 16926 res = AST_RTP_TRY_NATIVE; 16927 16928 ast_mutex_unlock(&p->lock); 16929 16930 return res; 16931 }
| static int sip_handle_t38_reinvite | ( | struct ast_channel * | chan, | |
| struct sip_pvt * | pvt, | |||
| int | reinvite | |||
| ) | [static] |
Handle T38 reinvite.
Definition at line 16797 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_get_local_max_datagram(), ast_udptl_get_peer(), ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), ast_udptl_set_local_max_datagram(), sip_pvt::flags, sip_pvt::initreq, t38properties::jointcapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, sip_pvt::ourip, sip_pvt::owner, t38properties::peercapability, sip_pvt::pendinginvite, SIP_CAN_REINVITE, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, t38properties::state, sip_pvt::t38, T38_ENABLED, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), transmit_response_with_t38_sdp(), sip_pvt::udptl, sip_pvt::udptlredirip, and XMIT_CRITICAL.
Referenced by handle_request_invite(), and handle_response_invite().
16798 { 16799 struct sip_pvt *p; 16800 int flag = 0; 16801 16802 p = chan->tech_pvt; 16803 if (!p || !pvt->udptl) 16804 return -1; 16805 16806 /* Setup everything on the other side like offered/responded from first side */ 16807 ast_mutex_lock(&p->lock); 16808 16809 /*! \todo check if this is not set earlier when setting up the PVT. If not 16810 maybe it should move there. */ 16811 p->t38.jointcapability = p->t38.peercapability = pvt->t38.jointcapability; 16812 16813 ast_udptl_set_far_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 16814 ast_udptl_set_local_max_datagram(p->udptl, ast_udptl_get_local_max_datagram(pvt->udptl)); 16815 ast_udptl_set_error_correction_scheme(p->udptl, ast_udptl_get_error_correction_scheme(pvt->udptl)); 16816 16817 if (reinvite) { /* If we are handling sending re-invite to the other side of the bridge */ 16818 /*! \note The SIP_CAN_REINVITE flag is for RTP media redirects, 16819 not really T38 re-invites which are different. In this 16820 case it's used properly, to see if we can reinvite over 16821 NAT 16822 */ 16823 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 16824 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 16825 flag =1; 16826 } else { 16827 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 16828 } 16829 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 16830 if (!p->pendinginvite) { 16831 if (option_debug > 2) { 16832 if (flag) 16833 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)); 16834 else 16835 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)); 16836 } 16837 transmit_reinvite_with_t38_sdp(p); 16838 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 16839 if (option_debug > 2) { 16840 if (flag) 16841 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)); 16842 else 16843 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)); 16844 } 16845 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 16846 } 16847 } 16848 /* Reset lastrtprx timer */ 16849 p->lastrtprx = p->lastrtptx = time(NULL); 16850 ast_mutex_unlock(&p->lock); 16851 return 0; 16852 } else { /* If we are handling sending 200 OK to the other side of the bridge */ 16853 if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE) && ast_test_flag(&pvt->flags[0], SIP_CAN_REINVITE)) { 16854 ast_udptl_get_peer(pvt->udptl, &p->udptlredirip); 16855 flag = 1; 16856 } else { 16857 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 16858 } 16859 if (option_debug > 2) { 16860 if (flag) 16861 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)); 16862 else 16863 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)); 16864 } 16865 pvt->t38.state = T38_ENABLED; 16866 p->t38.state = T38_ENABLED; 16867 if (option_debug > 1) { 16868 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", pvt->t38.state, pvt->owner ? pvt->owner->name : "<none>"); 16869 ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>"); 16870 } 16871 transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL); 16872 p->lastrtprx = p->lastrtptx = time(NULL); 16873 ast_mutex_unlock(&p->lock); 16874 return 0; 16875 } 16876 }
| 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 3278 of file chan_sip.c.
References __sip_pretend_ack(), ast_channel::_state, append_history, ast_clear_flag, ast_dsp_free(), AST_FLAG_ZOMBIE, ast_log(), ast_module_unref(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_quality(), ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, sip_pvt::autokillid, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, INC_CALL_LIMIT, INV_CALLING, INV_COMPLETED, sip_pvt::invitestate, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, SIP_ALREADYGONE, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_DEFER_BYE_ON_TRANSFER, SIP_INC_COUNT, SIP_NEEDDESTROY, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_OUTGOING, SIP_PENDINGBYE, sip_scheddestroy(), sipdebug, ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, update_call_counter(), sip_pvt::vad, and XMIT_RELIABLE.
03279 { 03280 struct sip_pvt *p = ast->tech_pvt; 03281 int needcancel = FALSE; 03282 int needdestroy = 0; 03283 struct ast_channel *oldowner = ast; 03284 03285 if (!p) { 03286 if (option_debug) 03287 ast_log(LOG_DEBUG, "Asked to hangup channel that was not connected\n"); 03288 return 0; 03289 } 03290 03291 if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) { 03292 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT)) { 03293 if (option_debug && sipdebug) 03294 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03295 update_call_counter(p, DEC_CALL_LIMIT); 03296 } 03297 if (option_debug >3) 03298 ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); 03299 if (p->autokillid > -1) 03300 sip_cancel_destroy(p); 03301 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03302 ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */ 03303 ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY); 03304 p->owner->tech_pvt = NULL; 03305 p->owner = NULL; /* Owner will be gone after we return, so take it away */ 03306 return 0; 03307 } 03308 if (option_debug) { 03309 if (ast_test_flag(ast, AST_FLAG_ZOMBIE) && p->refer && option_debug) 03310 ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid); 03311 else { 03312 if (option_debug) 03313 ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid); 03314 } 03315 } 03316 if (option_debug && ast_test_flag(ast, AST_FLAG_ZOMBIE)) 03317 ast_log(LOG_DEBUG, "Hanging up zombie call. Be scared.\n"); 03318 03319 ast_mutex_lock(&p->lock); 03320 if (ast_test_flag(&p->flags[0], SIP_INC_COUNT)) { 03321 if (option_debug && sipdebug) 03322 ast_log(LOG_DEBUG, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username); 03323 update_call_counter(p, DEC_CALL_LIMIT); 03324 } 03325 03326 /* Determine how to disconnect */ 03327 if (p->owner != ast) { 03328 ast_log(LOG_WARNING, "Huh? We aren't the owner? Can't hangup call.\n"); 03329 ast_mutex_unlock(&p->lock); 03330 return 0; 03331 } 03332 /* If the call is not UP, we need to send CANCEL instead of BYE */ 03333 if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) { 03334 needcancel = TRUE; 03335 if (option_debug > 3) 03336 ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state)); 03337 } 03338 03339 /* Disconnect */ 03340 if (p->vad) 03341 ast_dsp_free(p->vad); 03342 03343 p->owner = NULL; 03344 ast->tech_pvt = NULL; 03345 03346 ast_module_unref(ast_module_info->self); 03347 03348 /* Do not destroy this pvt until we have timeout or 03349 get an answer to the BYE or INVITE/CANCEL 03350 If we get no answer during retransmit period, drop the call anyway. 03351 (Sorry, mother-in-law, you can't deny a hangup by sending 03352 603 declined to BYE...) 03353 */ 03354 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) 03355 needdestroy = 1; /* Set destroy flag at end of this function */ 03356 else if (p->invitestate != INV_CALLING) 03357 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03358 03359 /* Start the process if it's not already started */ 03360 if (!ast_test_flag(&p->flags[0], SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { 03361 if (needcancel) { /* Outgoing call, not up */ 03362 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03363 /* stop retransmitting an INVITE that has not received a response */ 03364 __sip_pretend_ack(p); 03365 03366 /* if we can't send right now, mark it pending */ 03367 if (p->invitestate == INV_CALLING) { 03368 /* We can't send anything in CALLING state */ 03369 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03370 /* Do we need a timer here if we don't hear from them at all? */ 03371 } else { 03372 /* Send a new request: CANCEL */ 03373 transmit_request(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE); 03374 /* Actually don't destroy us yet, wait for the 487 on our original 03375 INVITE, but do set an autodestruct just in case we never get it. */ 03376 needdestroy = 0; 03377 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 03378 } 03379 if ( p->initid != -1 ) { 03380 /* channel still up - reverse dec of inUse counter 03381 only if the channel is not auto-congested */ 03382 update_call_counter(p, INC_CALL_LIMIT); 03383 } 03384 } else { /* Incoming call, not up */ 03385 const char *res; 03386 if (ast->hangupcause && (res = hangup_cause2sip(ast->hangupcause))) 03387 transmit_response_reliable(p, res, &p->initreq); 03388 else 03389 transmit_response_reliable(p, "603 Declined", &p->initreq); 03390 } 03391 } else { /* Call is in UP state, send BYE */ 03392 if (!p->pendinginvite) { 03393 char *audioqos = ""; 03394 char *videoqos = ""; 03395 if (p->rtp) 03396 audioqos = ast_rtp_get_quality(p->rtp, NULL); 03397 if (p->vrtp) 03398 videoqos = ast_rtp_get_quality(p->vrtp, NULL); 03399 /* Send a hangup */ 03400 transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); 03401 03402 /* Get RTCP quality before end of call */ 03403 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 03404 if (p->rtp) 03405 append_history(p, "RTCPaudio", "Quality:%s", audioqos); 03406 if (p->vrtp) 03407 append_history(p, "RTCPvideo", "Quality:%s", videoqos); 03408 } 03409 if (p->rtp && oldowner) 03410 pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos); 03411 if (p->vrtp && oldowner) 03412 pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos); 03413 } else { 03414 /* Note we will need a BYE when this all settles out 03415 but we can't send one while we have "INVITE" outstanding. */ 03416 ast_set_flag(&p->flags[0], SIP_PENDINGBYE); 03417 ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 03418 sip_cancel_destroy(p); 03419 } 03420 } 03421 } 03422 if (needdestroy) 03423 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 03424 ast_mutex_unlock(&p->lock); 03425 return 0; 03426 }
| 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 3666 of file chan_sip.c.
References ast_channel::_state, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, sip_pvt::flags, sip_pvt::initreq, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, sip_pvt::lock, LOG_WARNING, sip_alreadygone(), SIP_NOVIDEO, SIP_OUTGOING, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_YES, SIP_PROGRESS_SENT, SIP_RINGING, ast_channel::tech_pvt, transmit_info_with_vidupdate(), transmit_response(), transmit_response_with_sdp(), sip_pvt::vrtp, and XMIT_UNRELIABLE.
03667 { 03668 struct sip_pvt *p = ast->tech_pvt; 03669 int res = 0; 03670 03671 ast_mutex_lock(&p->lock); 03672 switch(condition) { 03673 case AST_CONTROL_RINGING: 03674 if (ast->_state == AST_STATE_RING) { 03675 p->invitestate = INV_EARLY_MEDIA; 03676 if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || 03677 (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { 03678 /* Send 180 ringing if out-of-band seems reasonable */ 03679 transmit_response(p, "180 Ringing", &p->initreq); 03680 ast_set_flag(&p->flags[0], SIP_RINGING); 03681 if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) 03682 break; 03683 } else { 03684 /* Well, if it's not reasonable, just send in-band */ 03685 } 03686 } 03687 res = -1; 03688 break; 03689 case AST_CONTROL_BUSY: 03690 if (ast->_state != AST_STATE_UP) { 03691 transmit_response(p, "486 Busy Here", &p->initreq); 03692 p->invitestate = INV_COMPLETED; 03693 sip_alreadygone(p); 03694 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03695 break; 03696 } 03697 res = -1; 03698 break; 03699 case AST_CONTROL_CONGESTION: 03700 if (ast->_state != AST_STATE_UP) { 03701 transmit_response(p, "503 Service Unavailable", &p->initreq); 03702 p->invitestate = INV_COMPLETED; 03703 sip_alreadygone(p); 03704 ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV); 03705 break; 03706 } 03707 res = -1; 03708 break; 03709 case AST_CONTROL_PROCEEDING: 03710 if ((ast->_state != AST_STATE_UP) && 03711 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03712 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03713 transmit_response(p, "100 Trying", &p->initreq); 03714 p->invitestate = INV_PROCEEDING; 03715 break; 03716 } 03717 res = -1; 03718 break; 03719 case AST_CONTROL_PROGRESS: 03720 if ((ast->_state != AST_STATE_UP) && 03721 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03722 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03723 p->invitestate = INV_EARLY_MEDIA; 03724 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03725 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03726 break; 03727 } 03728 res = -1; 03729 break; 03730 case AST_CONTROL_HOLD: 03731 ast_moh_start(ast, data, p->mohinterpret); 03732 break; 03733 case AST_CONTROL_UNHOLD: 03734 ast_moh_stop(ast); 03735 break; 03736 case AST_CONTROL_VIDUPDATE: /* Request a video frame update */ 03737 if (p->vrtp && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) { 03738 transmit_info_with_vidupdate(p); 03739 /* ast_rtcp_send_h261fur(p->vrtp); */ 03740 } else 03741 res = -1; 03742 break; 03743 case -1: 03744 res = -1; 03745 break; 03746 default: 03747 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition); 03748 res = -1; 03749 break; 03750 } 03751 ast_mutex_unlock(&p->lock); 03752 return res; 03753 }
| static const char * sip_nat_mode | ( | const struct sip_pvt * | p | ) | [static] |
Display SIP nat mode.
Definition at line 1733 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().
01734 { 01735 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT"; 01736 }
| 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 3762 of file chan_sip.c.
References accountcode, ast_channel::adsicpe, ast_channel::amaflags, sip_pvt::amaflags, append_history, AST_ADSI_UNAVAILABLE, ast_best_codec(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc(), ast_codec_choose(), ast_dsp_digitmode(), ast_dsp_new(), ast_dsp_set_features(), AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_fd(), sip_pvt::callgroup, ast_channel::callgroup, sip_pvt::callingpres, sip_pvt::capability, sip_pvt::chanvars, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_channel::context, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DTMF_DETECT, ast_channel::exten, ast_channel::fds, sip_pvt::flags, fmt, global_jbconf, ast_channel::hangupcause, sip_pvt::jointcapability, language, sip_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_variable::name, ast_channel::nativeformats, ast_variable::next, option_debug, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pickupgroup, ast_channel::pickupgroup, sip_pvt::prefcodec, sip_pvt::prefs, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::rings, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_NO_HISTORY, sip_tech, sip_tech_info, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::udptl, sip_pvt::vad, ast_variable::value, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by handle_request_invite(), and sip_request_call().
03763 { 03764 struct ast_channel *tmp; 03765 struct ast_variable *v = NULL; 03766 int fmt; 03767 int what; 03768 int needvideo = 0; 03769 { 03770 const char *my_name; /* pick a good name */ 03771 03772 if (title) 03773 my_name = title; 03774 else if ( (my_name = strchr(i->fromdomain,':')) ) 03775 my_name++; /* skip ':' */ 03776 else 03777 my_name = i->fromdomain; 03778 03779 ast_mutex_unlock(&i->lock); 03780 /* Don't hold a sip pvt lock while we allocate a channel */ 03781 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); 03782 03783 } 03784 if (!tmp) { 03785 ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n"); 03786 return NULL; 03787 } 03788 ast_mutex_lock(&i->lock); 03789 03790 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO) 03791 tmp->tech = &sip_tech_info; 03792 else 03793 tmp->tech = &sip_tech; 03794 03795 /* Select our native format based on codec preference until we receive 03796 something from another device to the contrary. */ 03797 if (i->jointcapability) /* The joint capabilities of us and peer */ 03798 what = i->jointcapability; 03799 else if (i->capability) /* Our configured capability for this peer */ 03800 what = i->capability; 03801 else 03802 what = global_capability; /* Global codec support */ 03803 03804 /* Set the native formats for audio and merge in video */ 03805 tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | (i->jointcapability & AST_FORMAT_VIDEO_MASK); 03806 if (option_debug > 2) { 03807 char buf[BUFSIZ]; 03808 ast_log(LOG_DEBUG, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, BUFSIZ, tmp->nativeformats)); 03809 ast_log(LOG_DEBUG, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->jointcapability)); 03810 ast_log(LOG_DEBUG, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->capability)); 03811 ast_log(LOG_DEBUG, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, BUFSIZ, ast_codec_choose(&i->prefs, what, 1))); 03812 if (i->prefcodec) 03813 ast_log(LOG_DEBUG, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, BUFSIZ, i->prefcodec)); 03814 } 03815 03816 /* XXX Why are we choosing a codec from the native formats?? */ 03817 fmt = ast_best_codec(tmp->nativeformats); 03818 03819 /* If we have a prefcodec setting, we have an inbound channel that set a 03820 preferred format for this call. Otherwise, we check the jointcapability 03821 We also check for vrtp. If it's not there, we are not allowed do any video anyway. 03822 */ 03823 if (i->vrtp) { 03824 if (i->prefcodec) 03825 needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK; /* Outbound call */ 03826 else 03827 needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK; /* Inbound call */ 03828 } 03829 03830 if (option_debug > 2) { 03831 if (needvideo) 03832 ast_log(LOG_DEBUG, "This channel can handle video! HOLLYWOOD next!\n"); 03833 else 03834 ast_log(LOG_DEBUG, "This channel will not be able to handle video.\n"); 03835 } 03836 03837 03838 03839 if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) { 03840 i->vad = ast_dsp_new(); 03841 ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT); 03842 if (global_relaxdtmf) 03843 ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); 03844 } 03845 if (i->rtp) { 03846 tmp->fds[0] = ast_rtp_fd(i->rtp); 03847 tmp->fds[1] = ast_rtcp_fd(i->rtp); 03848 } 03849 if (needvideo && i->vrtp) { 03850 tmp->fds[2] = ast_rtp_fd(i->vrtp); 03851 tmp->fds[3] = ast_rtcp_fd(i->vrtp); 03852 } 03853 if (i->udptl) { 03854 tmp->fds[5] = ast_udptl_fd(i->udptl); 03855 } 03856 if (state == AST_STATE_RING) 03857 tmp->rings = 1; 03858 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 03859 tmp->writeformat = fmt; 03860 tmp->rawwriteformat = fmt; 03861 tmp->readformat = fmt; 03862 tmp->rawreadformat = fmt; 03863 tmp->tech_pvt = i; 03864 03865 tmp->callgroup = i->callgroup; 03866 tmp->pickupgroup = i->pickupgroup; 03867 tmp->cid.cid_pres = i->callingpres; 03868 if (!ast_strlen_zero(i->accountcode)) 03869 ast_string_field_set(tmp, accountcode, i->accountcode); 03870 if (i->amaflags) 03871 tmp->amaflags = i->amaflags; 03872 if (!ast_strlen_zero(i->language)) 03873 ast_string_field_set(tmp, language, i->language); 03874 i->owner = tmp; 03875 ast_module_ref(ast_module_info->self); 03876 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 03877 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 03878 03879 03880 /* Don't use ast_set_callerid() here because it will 03881 * generate an unnecessary NewCallerID event */ 03882 tmp->cid.cid_num = ast_strdup(i->cid_num); 03883 tmp->cid.cid_ani = ast_strdup(i->cid_num); 03884 tmp->cid.cid_name = ast_strdup(i->cid_name); 03885 if (!ast_strlen_zero(i->rdnis)) 03886 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 03887 03888 if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) 03889 tmp->cid.cid_dnid = ast_strdup(i->exten); 03890 03891 tmp->priority = 1; 03892 if (!ast_strlen_zero(i->uri)) 03893 pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri); 03894 if (!ast_strlen_zero(i->domain)) 03895 pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain); 03896 if (!ast_strlen_zero(i->useragent)) 03897 pbx_builtin_setvar_helper(tmp, "SIPUSERAGENT", i->useragent); 03898 if (!ast_strlen_zero(i->callid)) 03899 pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); 03900 if (i->rtp) 03901 ast_jb_configure(tmp, &global_jbconf); 03902 if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) { 03903 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 03904 tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 03905 ast_hangup(tmp); 03906 tmp = NULL; 03907 } 03908 /* Set channel variables for this call from configuration */ 03909 for (v = i->chanvars ; v ; v = v->next) 03910 pbx_builtin_setvar_helper(tmp,v->name,v->value); 03911 03912 if (!ast_test_flag(&i->flags[0], SIP_NO_HISTORY)) 03913 append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid); 03914 03915 return tmp; 03916 }
| static int sip_no_debug | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Disable SIP Debugging in CLI.
Definition at line 11026 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11027 { 11028 if (argc != 4) 11029 return RESULT_SHOWUSAGE; 11030 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11031 ast_cli(fd, "SIP Debugging Disabled\n"); 11032 return RESULT_SUCCESS; 11033 }
| static int sip_no_debug_deprecated | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 11035 of file chan_sip.c.
References ast_clear_flag, ast_cli(), global_flags, RESULT_SHOWUSAGE, RESULT_SUCCESS, and SIP_PAGE2_DEBUG_CONSOLE.
11036 { 11037 if (argc != 3) 11038 return RESULT_SHOWUSAGE; 11039 ast_clear_flag(&global_flags[1], SIP_PAGE2_DEBUG_CONSOLE); 11040 ast_cli(fd, "SIP Debugging Disabled\n"); 11041 return RESULT_SUCCESS; 11042 }
| static int sip_no_history | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Disable SIP History logging (CLI).
Definition at line 11056 of file chan_sip.c.
References ast_cli(), FALSE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
11057 { 11058 if (argc != 3) { 11059 return RESULT_SHOWUSAGE; 11060 } 11061 recordhistory = FALSE; 11062 ast_cli(fd, "SIP History Recording Disabled\n"); 11063 return RESULT_SUCCESS; 11064 }
| static int sip_notify | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Cli command to send SIP notify to peer.
Definition at line 10970 of file chan_sip.c.
References __ourip, add_header(), ast_cli(), ast_log(), ast_sip_ouraddrfor(), ast_variable_browse(), build_callid_pvt(), build_via(), create_addr(), DEFAULT_TRANS_TIMEOUT, initreqprep(), LOG_WARNING, notify_types, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_alloc(), sip_destroy(), SIP_NOTIFY, sip_scheddestroy(), transmit_sip_request(), and var.
10971 { 10972 struct ast_variable *varlist; 10973 int i; 10974 10975 if (argc < 4) 10976 return RESULT_SHOWUSAGE; 10977 10978 if (!notify_types) { 10979 ast_cli(fd, "No %s file found, or no types listed there\n", notify_config); 10980 return RESULT_FAILURE; 10981 } 10982 10983 varlist = ast_variable_browse(notify_types, argv[2]); 10984 10985 if (!varlist) { 10986 ast_cli(fd, "Unable to find notify type '%s'\n", argv[2]); 10987 return RESULT_FAILURE; 10988 } 10989 10990 for (i = 3; i < argc; i++) { 10991 struct sip_pvt *p; 10992 struct sip_request req; 10993 struct ast_variable *var; 10994 10995 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { 10996 ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n"); 10997 return RESULT_FAILURE; 10998 } 10999 11000 if (create_addr(p, argv[i])) { 11001 /* Maybe they're not registered, etc. */ 11002 sip_destroy(p); 11003 ast_cli(fd, "Could not create address for '%s'\n", argv[i]); 11004 continue; 11005 } 11006 11007 initreqprep(&req, p, SIP_NOTIFY); 11008 11009 for (var = varlist; var; var = var->next) 11010 add_header(&req, var->name, var->value); 11011 11012 /* Recalculate our side, and recalculate Call ID */ 11013 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 11014 p->ourip = __ourip; 11015 build_via(p); 11016 build_callid_pvt(p); 11017 ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]); 11018 transmit_sip_request(p, &req); 11019 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 11020 } 11021 11022 return RESULT_SUCCESS; 11023 }
| 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 12652 of file chan_sip.c.
References ast_channel::amaflags, ast_calloc, AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc(), ast_channel_lock, ast_channel_masquerade(), ast_channel_unlock, ast_do_masquerade(), ast_hangup(), ast_log(), ast_pthread_create_background, AST_STATE_DOWN, ast_channel::context, copy_request(), ast_channel::exten, free, ast_channel::hangupcause, LOG_DEBUG, LOG_WARNING, option_debug, ast_channel::priority, ast_channel::readformat, sip_park_thread(), and ast_channel::writeformat.
Referenced by handle_request_refer().
12653 { 12654 struct sip_dual *d; 12655 struct ast_channel *transferee, *transferer; 12656 /* Chan2m: The transferer, chan1m: The transferee */ 12657 pthread_t th; 12658 12659 transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 12660 transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); 12661 if ((!transferer) || (!transferee)) { 12662 if (transferee) { 12663 transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 12664 ast_hangup(transferee); 12665 } 12666 if (transferer) { 12667 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 12668 ast_hangup(transferer); 12669 } 12670 return -1; 12671 } 12672 12673 /* Make formats okay */ 12674 transferee->readformat = chan1->readformat; 12675 transferee->writeformat = chan1->writeformat; 12676 12677 /* Prepare for taking over the channel */ 12678 ast_channel_masquerade(transferee, chan1); 12679 12680 /* Setup the extensions and such */ 12681 ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context)); 12682 ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten)); 12683 transferee->priority = chan1->priority; 12684 12685 /* We make a clone of the peer channel too, so we can play 12686 back the announcement */ 12687 12688 /* Make formats okay */ 12689 transferer->readformat = chan2->readformat; 12690 transferer->writeformat = chan2->writeformat; 12691 12692 /* Prepare for taking over the channel */ 12693 ast_channel_masquerade(transferer, chan2); 12694 12695 /* Setup the extensions and such */ 12696 ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context)); 12697 ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten)); 12698 transferer->priority = chan2->priority; 12699 12700 ast_channel_lock(transferer); 12701 if (ast_do_masquerade(transferer)) { 12702 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 12703 ast_channel_unlock(transferer); 12704 transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 12705 ast_hangup(transferer); 12706 return -1; 12707 } 12708 ast_channel_unlock(transferer); 12709 if (!transferer || !transferee) { 12710 if (!transferer) { 12711 if (option_debug) 12712 ast_log(LOG_DEBUG, "No transferer channel, giving up parking\n"); 12713 } 12714 if (!transferee) { 12715 if (option_debug) 12716 ast_log(LOG_DEBUG, "No transferee channel, giving up parking\n"); 12717 } 12718 return -1; 12719 } 12720 if ((d = ast_calloc(1, sizeof(*d)))) { 12721 pthread_attr_t attr; 12722 12723 pthread_attr_init(&attr); 12724 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 12725 12726 /* Save original request for followup */ 12727 copy_request(&d->req, req); 12728 d->chan1 = transferee; /* Transferee */ 12729 d->chan2 = transferer; /* Transferer */ 12730 d->seqno = seqno; 12731 if (ast_pthread_create_background(&th, &attr, sip_park_thread, d) < 0) { 12732 /* Could not start thread */ 12733 free(d); /* We don't need it anymore. If thread is created, d will be free'd 12734 by sip_park_thread() */ 12735 pthread_attr_destroy(&attr); 12736 return 0; 12737 } 12738 pthread_attr_destroy(&attr); 12739 } 12740 return -1; 12741 }
| 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 12585 of file chan_sip.c.
References append_history, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_do_masquerade(), ast_hangup(), ast_log(), ast_park_call(), sip_dual::chan1, sip_dual::chan2, copy_request(), ext, free, ast_channel::hangupcause, LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, sip_dual::req, sip_dual::seqno, ast_channel::tech_pvt, transmit_message_with_text(), transmit_notify_with_sipfrag(), transmit_response(), and TRUE.
Referenced by sip_park().
12586 { 12587 struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */ 12588 struct sip_dual *d; 12589 struct sip_request req; 12590 int ext; 12591 int res; 12592 12593 d = stuff; 12594 transferee = d->chan1; 12595 transferer = d->chan2; 12596 copy_request(&req, &d->req); 12597 free(d); 12598 12599 if (!transferee || !transferer) { 12600 ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" ); 12601 return NULL; 12602 } 12603 if (option_debug > 3) 12604 ast_log(LOG_DEBUG, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name); 12605 12606 ast_channel_lock(transferee); 12607 if (ast_do_masquerade(transferee)) { 12608 ast_log(LOG_WARNING, "Masquerade failed.\n"); 12609 transmit_response(transferer->tech_pvt, "503 Internal error", &req); 12610 ast_channel_unlock(transferee); 12611 return NULL; 12612 } 12613 ast_channel_unlock(transferee); 12614 12615 res = ast_park_call(transferee, transferer, 0, &ext); 12616 12617 12618 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE 12619 if (!res) { 12620 transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n"); 12621 } else { 12622 /* Then tell the transferer what happened */ 12623 sprintf(buf, "Call parked on extension '%d'", ext); 12624 transmit_message_with_text(transferer->tech_pvt, buf); 12625 } 12626 #endif 12627 12628 /* Any way back to the current call??? */ 12629 /* Transmit response to the REFER request */ 12630 transmit_response(transferer->tech_pvt, "202 Accepted", &req); 12631 if (!res) { 12632 /* Transfer succeeded */ 12633 append_history(transferer->tech_pvt, "SIPpark","Parked call on %d", ext); 12634 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE); 12635 transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING; 12636 ast_hangup(transferer); /* This will cause a BYE */ 12637 if (option_debug) 12638 ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext); 12639 } else { 12640 transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE); 12641 append_history(transferer->tech_pvt, "SIPpark","Parking failed\n"); 12642 if (option_debug) 12643 ast_log(LOG_DEBUG, "SIP Call parked failed \n"); 12644 /* Do not hangup call */ 12645 } 12646 return NULL; 12647 }
| 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 8203 of file chan_sip.c.
References ast_device_state_changed(), find_peer(), and sip_peer::onHold.
Referenced by process_sdp(), and update_call_counter().
08204 { 08205 struct sip_peer *peer = find_peer(p->peername, NULL, 1); 08206 08207 if (!peer) 08208 return; 08209 08210 /* If they put someone on hold, increment the value... otherwise decrement it */ 08211 if (hold) 08212 peer->onHold++; 08213 else 08214 peer->onHold--; 08215 08216 /* Request device state update */ 08217 ast_device_state_changed("SIP/%s", peer->name); 08218 08219 return; 08220 }
| 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 17175 of file chan_sip.c.
References ast_sched_add(), ast_sched_del(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, peerl, sched, and sip_poke_peer_s().
Referenced by load_module().
17176 { 17177 int ms = 0; 17178 17179 if (!speerobjs) /* No peers, just give up */ 17180 return; 17181 17182 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 17183 ASTOBJ_WRLOCK(iterator); 17184 if (iterator->pokeexpire > -1) 17185 ast_sched_del(sched, iterator->pokeexpire); 17186 ms += 100; 17187 iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, iterator); 17188 ASTOBJ_UNLOCK(iterator); 17189 } while (0) 17190 ); 17191 }
| static int sip_poke_noanswer | ( | void * | data | ) | [static] |
React to lack of answer to Qualify poke.
Definition at line 15207 of file chan_sip.c.
References ast_device_state_changed(), ast_log(), ast_sched_add(), sip_peer::call, DEFAULT_FREQ_NOTOK, EVENT_FLAG_SYSTEM, sip_peer::lastms, LOG_NOTICE, manager_event(), sip_peer::pokeexpire, sched, sip_destroy(), and sip_poke_peer_s().
Referenced by sip_poke_peer().
15208 { 15209 struct sip_peer *peer = data; 15210 15211 peer->pokeexpire = -1; 15212 if (peer->lastms > -1) { 15213 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Last qualify: %d\n", peer->name, peer->lastms); 15214 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1); 15215 } 15216 if (peer->call) 15217 sip_destroy(peer->call); 15218 peer->call = NULL; 15219 peer->lastms = -1; 15220 ast_device_state_changed("SIP/%s", peer->name); 15221 /* Try again quickly */ 15222 peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer); 15223 return 0; 15224 }
| static int sip_poke_peer | ( | struct sip_peer * | peer | ) | [static] |
Check availability of peer, also keep NAT open.
Definition at line 15229 of file chan_sip.c.
References __ourip, sip_peer::addr, ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_set, ast_strlen_zero(), build_callid_pvt(), build_via(), sip_peer::call, DEFAULT_MAXMS, sip_peer::flags, sip_pvt::flags, sip_peer::fullcontact, sip_peer::lastms, LOG_NOTICE, sip_peer::maxms, sip_pvt::ourip, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::recv, sip_pvt::relatedpeer, sip_pvt::sa, sched, sip_alloc(), sip_destroy(), SIP_FLAGS_TO_COPY, SIP_INVITE, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_FLAGS_TO_COPY, sip_poke_noanswer(), sipdebug, sip_peer::tohost, and transmit_invite().
Referenced by parse_register_contact(), reg_source_db(), and sip_poke_peer_s().
15230 { 15231 struct sip_pvt *p; 15232 15233 if (!peer->maxms || !peer->addr.sin_addr.s_addr) { 15234 /* IF we have no IP, or this isn't to be monitored, return 15235 imeediately after clearing things out */ 15236 if (peer->pokeexpire > -1) 15237 ast_sched_del(sched, peer->pokeexpire); 15238 peer->lastms = 0; 15239 peer->pokeexpire = -1; 15240 peer->call = NULL; 15241 return 0; 15242 } 15243 if (peer->call) { 15244 if (sipdebug) 15245 ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n"); 15246 sip_destroy(peer->call); 15247 } 15248 if (!(p = peer->call = sip_alloc(NULL, NULL, 0, SIP_OPTIONS))) 15249 return -1; 15250 15251 p->sa = peer->addr; 15252 p->recv = peer->addr; 15253 ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY); 15254 ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY); 15255 15256 /* Send OPTIONs to peer's fullcontact */ 15257 if (!ast_strlen_zero(peer->fullcontact)) 15258 ast_string_field_set(p, fullcontact, peer->fullcontact); 15259 15260 if (!ast_strlen_zero(peer->tohost)) 15261 ast_string_field_set(p, tohost, peer->tohost); 15262 else 15263 ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr)); 15264 15265 /* Recalculate our side, and recalculate Call ID */ 15266 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15267 p->ourip = __ourip; 15268 build_via(p); 15269 build_callid_pvt(p); 15270 15271 if (peer->pokeexpire > -1) 15272 ast_sched_del(sched, peer->pokeexpire); 15273 p->relatedpeer = peer; 15274 ast_set_flag(&p->flags[0], SIP_OUTGOING); 15275 #ifdef VOCAL_DATA_HACK 15276 ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username)); 15277 transmit_invite(p, SIP_INVITE, 0, 2); 15278 #else 15279 transmit_invite(p, SIP_OPTIONS, 0, 2); 15280 #endif 15281 gettimeofday(&peer->ps, NULL); 15282 peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer); 15283 15284 return 0; 15285 }
| static int sip_poke_peer_s | ( | void * | data | ) | [static] |
Poke peer (send qualify to check if peer is alive and well).
Definition at line 7607 of file chan_sip.c.
References sip_peer::pokeexpire, and sip_poke_peer().
Referenced by handle_response_peerpoke(), reg_source_db(), sip_poke_all_peers(), and sip_poke_noanswer().
07608 { 07609 struct sip_peer *peer = data; 07610 07611 peer->pokeexpire = -1; 07612 sip_poke_peer(peer); 07613 return 0; 07614 }
| static int sip_prune_realtime | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Remove temporary realtime objects from memory (CLI).
Definition at line 9763 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.
09764 { 09765 struct sip_peer *peer; 09766 struct sip_user *user; 09767 int pruneuser = FALSE; 09768 int prunepeer = FALSE; 09769 int multi = FALSE; 09770 char *name = NULL; 09771 regex_t regexbuf; 09772 09773 switch (argc) { 09774 case 4: 09775 if (!strcasecmp(argv[3], "user")) 09776 return RESULT_SHOWUSAGE; 09777 if (!strcasecmp(argv[3], "peer")) 09778 return RESULT_SHOWUSAGE; 09779 if (!strcasecmp(argv[3], "like")) 09780 return RESULT_SHOWUSAGE; 09781 if (!strcasecmp(argv[3], "all")) { 09782 multi = TRUE; 09783 pruneuser = prunepeer = TRUE; 09784 } else { 09785 pruneuser = prunepeer = TRUE; 09786 name = argv[3]; 09787 } 09788 break; 09789 case 5: 09790 if (!strcasecmp(argv[4], "like")) 09791 return RESULT_SHOWUSAGE; 09792 if (!strcasecmp(argv[3], "all")) 09793 return RESULT_SHOWUSAGE; 09794 if (!strcasecmp(argv[3], "like")) { 09795 multi = TRUE; 09796 name = argv[4]; 09797 pruneuser = prunepeer = TRUE; 09798 } else if (!strcasecmp(argv[3], "user")) { 09799 pruneuser = TRUE; 09800 if (!strcasecmp(argv[4], "all")) 09801 multi = TRUE; 09802 else 09803 name = argv[4]; 09804 } else if (!strcasecmp(argv[3], "peer")) { 09805 prunepeer = TRUE; 09806 if (!strcasecmp(argv[4], "all")) 09807 multi = TRUE; 09808 else 09809 name = argv[4]; 09810 } else 09811 return RESULT_SHOWUSAGE; 09812 break; 09813 case 6: 09814 if (strcasecmp(argv[4], "like")) 09815 return RESULT_SHOWUSAGE; 09816 if (!strcasecmp(argv[3], "user")) { 09817 pruneuser = TRUE; 09818 name = argv[5]; 09819 } else if (!strcasecmp(argv[3], "peer")) { 09820 prunepeer = TRUE; 09821 name = argv[5]; 09822 } else 09823 return RESULT_SHOWUSAGE; 09824 break; 09825 default: 09826 return RESULT_SHOWUSAGE; 09827 } 09828 09829 if (multi && name) { 09830 if (regcomp(®exbuf, name, REG_EXTENDED | REG_NOSUB)) 09831 return RESULT_SHOWUSAGE; 09832 } 09833 09834 if (multi) { 09835 if (prunepeer) { 09836 int pruned = 0; 09837 09838 ASTOBJ_CONTAINER_WRLOCK(&peerl); 09839 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09840 ASTOBJ_RDLOCK(iterator); 09841 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09842 ASTOBJ_UNLOCK(iterator); 09843 continue; 09844 }; 09845 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 09846 ASTOBJ_MARK(iterator); 09847 pruned++; 09848 } 09849 ASTOBJ_UNLOCK(iterator); 09850 } while (0) ); 09851 if (pruned) { 09852 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, sip_destroy_peer); 09853 ast_cli(fd, "%d peers pruned.\n", pruned); 09854 } else 09855 ast_cli(fd, "No peers found to prune.\n"); 09856 ASTOBJ_CONTAINER_UNLOCK(&peerl); 09857 } 09858 if (pruneuser) { 09859 int pruned = 0; 09860 09861 ASTOBJ_CONTAINER_WRLOCK(&userl); 09862 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09863 ASTOBJ_RDLOCK(iterator); 09864 if (name && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09865 ASTOBJ_UNLOCK(iterator); 09866 continue; 09867 }; 09868 if (ast_test_flag(&iterator->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 09869 ASTOBJ_MARK(iterator); 09870 pruned++; 09871 } 09872 ASTOBJ_UNLOCK(iterator); 09873 } while (0) ); 09874 if (pruned) { 09875 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, sip_destroy_user); 09876 ast_cli(fd, "%d users pruned.\n", pruned); 09877 } else 09878 ast_cli(fd, "No users found to prune.\n"); 09879 ASTOBJ_CONTAINER_UNLOCK(&userl); 09880 } 09881 } else { 09882 if (prunepeer) { 09883 if ((peer = ASTOBJ_CONTAINER_FIND_UNLINK(&peerl, name))) { 09884 if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 09885 ast_cli(fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name); 09886 ASTOBJ_CONTAINER_LINK(&peerl, peer); 09887 } else 09888 ast_cli(fd, "Peer '%s' pruned.\n", name); 09889 ASTOBJ_UNREF(peer, sip_destroy_peer); 09890 } else 09891 ast_cli(fd, "Peer '%s' not found.\n", name); 09892 } 09893 if (pruneuser) { 09894 if ((user = ASTOBJ_CONTAINER_FIND_UNLINK(&userl, name))) { 09895 if (!ast_test_flag(&user->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) { 09896 ast_cli(fd, "User '%s' is not a Realtime user, cannot be pruned.\n", name); 09897 ASTOBJ_CONTAINER_LINK(&userl, user); 09898 } else 09899 ast_cli(fd, "User '%s' pruned.\n", name); 09900 ASTOBJ_UNREF(user, sip_destroy_user); 09901 } else 09902 ast_cli(fd, "User '%s' not found.\n", name); 09903 } 09904 } 09905 09906 return RESULT_SUCCESS; 09907 }
| static struct ast_frame * sip_read | ( | struct ast_channel * | ast | ) | [static] |
Read SIP RTP from channel.
Definition at line 4119 of file chan_sip.c.
References ast_bridged_channel(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, FALSE, sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lock, LOG_DEBUG, option_debug, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PENDINGBYE, sip_rtp_read(), t38properties::state, sip_pvt::t38, T38_DISABLED, T38_LOCAL_REINVITE, t38properties::t38support, ast_channel::tech_pvt, and transmit_reinvite_with_t38_sdp().
04120 { 04121 struct ast_frame *fr; 04122 struct sip_pvt *p; 04123 04124 if( ast == NULL ) 04125 return NULL; 04126 04127 p = ast->tech_pvt; 04128 int faxdetected = FALSE; 04129 04130 if( p == NULL ) 04131 return NULL; 04132 04133 ast_mutex_lock(&p->lock); 04134 fr = sip_rtp_read(ast, p, &faxdetected); 04135 p->lastrtprx = time(NULL); 04136 04137 /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */ 04138 /* 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 */ 04139 if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) { 04140 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 04141 if (!p->pendinginvite) { 04142 if (option_debug > 2) 04143 ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name); 04144 p->t38.state = T38_LOCAL_REINVITE; 04145 transmit_reinvite_with_t38_sdp(p); 04146 if (option_debug > 1) 04147 ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name); 04148 } 04149 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 04150 if (option_debug > 2) 04151 ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name); 04152 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 04153 } 04154 } 04155 04156 ast_mutex_unlock(&p->lock); 04157 return fr; 04158 }
| static struct sockaddr_in * sip_real_dst | ( | const struct sip_pvt * | p | ) | [static] |
The real destination address for a write.
Definition at line 1727 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().
01728 { 01729 return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa; 01730 }
| static int sip_refer_allocate | ( | struct sip_pvt * | p | ) | [static] |
Allocate SIP refer structure.
Definition at line 7418 of file chan_sip.c.
References ast_calloc, and sip_pvt::refer.
Referenced by handle_request_invite(), handle_request_refer(), and transmit_refer().
07419 { 07420 p->refer = ast_calloc(1, sizeof(struct sip_refer)); 07421 return p->refer ? 1 : 0; 07422 }
| static int sip_reg_timeout | ( | void * | data | ) | [static] |
Registration timeout, register again.
Definition at line 7175 of file chan_sip.c.
References __sip_pretend_ack(), ast_log(), ast_set_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, EVENT_FLAG_SYSTEM, sip_pvt::flags, LOG_NOTICE, manager_event(), REG_STATE_FAILED, REG_STATE_UNREGISTERED, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, regstate2str(), SIP_NEEDDESTROY, SIP_REGISTER, sip_registry_destroy(), sip_registry::timeout, and transmit_register().
Referenced by transmit_register().
07176 { 07177 07178 /* if we are here, our registration timed out, so we'll just do it over */ 07179 struct sip_registry *r = ASTOBJ_REF((struct sip_registry *) data); 07180 struct sip_pvt *p; 07181 int res; 07182 07183 /* if we couldn't get a reference to the registry object, punt */ 07184 if (!r) 07185 return 0; 07186 07187 ast_log(LOG_NOTICE, " -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 07188 if (r->call) { 07189 /* Unlink us, destroy old call. Locking is not relevant here because all this happens 07190 in the single SIP manager thread. */ 07191 p = r->call; 07192 if (p->registry) 07193 ASTOBJ_UNREF(p->registry, sip_registry_destroy); 07194 r->call = NULL; 07195 ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 07196 /* Pretend to ACK anything just in case */ 07197 __sip_pretend_ack(p); /* XXX we need p locked, not sure we have */ 07198 } 07199 /* If we have a limit, stop registration and give up */ 07200 if (global_regattempts_max && (r->regattempts > global_regattempts_max)) { 07201 /* Ok, enough is enough. Don't try any more */ 07202 /* We could add an external notification here... 07203 steal it from app_voicemail :-) */ 07204 ast_log(LOG_NOTICE, " -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname); 07205 r->regstate = REG_STATE_FAILED; 07206 } else { 07207 r->regstate = REG_STATE_UNREGISTERED; 07208 r->timeout = -1; 07209 res=transmit_register(r, SIP_REGISTER, NULL, NULL); 07210 } 07211 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)); 07212 ASTOBJ_UNREF(r, sip_registry_destroy); 07213 return 0; 07214 }
| static int sip_register | ( | char * | value, | |
| int | lineno | |||
| ) | [static] |
Parse register=> line in sip.conf and add to registry.
Definition at line 4446 of file chan_sip.c.
References ast_calloc, ast_log(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, ASTOBJ_UNREF, FALSE, free, hostname, INITIAL_CSEQ, LOG_ERROR, LOG_WARNING, regl, secret, sip_registry_destroy(), and username.
04447 { 04448 struct sip_registry *reg; 04449 int portnum = 0; 04450 char username[256] = ""; 04451 char *hostname=NULL, *secret=NULL, *authuser=NULL; 04452 char *porta=NULL; 04453 char *contact=NULL; 04454 04455 if (!value) 04456 return -1; 04457 ast_copy_string(username, value, sizeof(username)); 04458 /* First split around the last '@' then parse the two components. */ 04459 hostname = strrchr(username, '@'); /* allow @ in the first part */ 04460 if (hostname) 04461 *hostname++ = '\0'; 04462 if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) { 04463 ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno); 04464 return -1; 04465 } 04466 /* split user[:secret[:authuser]] */ 04467 secret = strchr(username, ':'); 04468 if (secret) { 04469 *secret++ = '\0'; 04470 authuser = strchr(secret, ':'); 04471 if (authuser) 04472 *authuser++ = '\0'; 04473 } 04474 /* split host[:port][/contact] */ 04475 contact = strchr(hostname, '/'); 04476 if (contact) 04477 *contact++ = '\0'; 04478 if (ast_strlen_zero(contact)) 04479 contact = "s"; 04480 porta = strchr(hostname, ':'); 04481 if (porta) { 04482 *porta++ = '\0'; 04483 portnum = atoi(porta); 04484 if (portnum == 0) { 04485 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 04486 return -1; 04487 } 04488 } 04489 if (!(reg = ast_calloc(1, sizeof(*reg)))) { 04490 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n"); 04491 return -1; 04492 } 04493 04494 if (ast_string_field_init(reg, 256)) { 04495 ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n"); 04496 free(reg); 04497 return -1; 04498 } 04499 04500 regobjs++; 04501 ASTOBJ_INIT(reg); 04502 ast_string_field_set(reg, contact, contact); 04503 if (username) 04504 ast_string_field_set(reg, username, username); 04505 if (hostname) 04506 ast_string_field_set(reg, hostname, hostname); 04507 if (authuser) 04508 ast_string_field_set(reg, authuser, authuser); 04509 if (secret) 04510 ast_string_field_set(reg, secret, secret); 04511 reg->expire = -1; 04512 reg->timeout = -1; 04513 reg->refresh = default_expiry; 04514 reg->portno = portnum; 04515 reg->callid_valid = FALSE; 04516 reg->ocseq = INITIAL_CSEQ; 04517 ASTOBJ_CONTAINER_LINK(®l, reg); /* Add the new registry entry to the list */ 04518 ASTOBJ_UNREF(reg,sip_registry_destroy); 04519 return 0; 04520 }
| 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 2859 of file chan_sip.c.
References ast_log(), ast_sched_del(), ast_string_field_free_pools, sip_registry::call, sip_registry::expire, free, LOG_DEBUG, option_debug, sip_pvt::registry, sched, sip_destroy(), and sip_registry::timeout.
Referenced by __sip_destroy(), handle_response_register(), sip_reg_timeout(), sip_register(), sip_reregister(), and unload_module().
02860 { 02861 /* Really delete */ 02862 if (option_debug > 2) 02863 ast_log(LOG_DEBUG, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname); 02864 02865 if (reg->call) { 02866 /* Clear registry before destroying to ensure 02867 we don't get reentered trying to grab the registry lock */ 02868 reg->call->registry = NULL; 02869 if (option_debug > 2) 02870 ast_log(LOG_DEBUG, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname); 02871 sip_destroy(reg->call); 02872 } 02873 if (reg->expire > -1) 02874 ast_sched_del(sched, reg->expire); 02875 if (reg->timeout > -1) 02876 ast_sched_del(sched, reg->timeout); 02877 ast_string_field_free_pools(reg); 02878 regobjs--; 02879 free(reg); 02880 02881 }
| static int sip_reload | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Force reload of module from cli.
Definition at line 17267 of file chan_sip.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), CHANNEL_CLI_RELOAD, CHANNEL_MODULE_RELOAD, restart_monitor(), and TRUE.
Referenced by reload().
17268 { 17269 ast_mutex_lock(&sip_reload_lock); 17270 if (sip_reloading) 17271 ast_verbose("Previous SIP reload not yet done\n"); 17272 else { 17273 sip_reloading = TRUE; 17274 if (fd) 17275 sip_reloadreason = CHANNEL_CLI_RELOAD; 17276 else 17277 sip_reloadreason = CHANNEL_MODULE_RELOAD; 17278 } 17279 ast_mutex_unlock(&sip_reload_lock); 17280 restart_monitor(); 17281 17282 return 0; 17283 }
| 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 15387 of file chan_sip.c.
References __ourip, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, AST_FORMAT_MAX_AUDIO, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), build_callid_pvt(), build_via(), create_addr(), ext, sip_pvt::flags, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, option_debug, sip_pvt::options, restart_monitor(), sip_alloc(), sip_destroy(), SIP_INVITE, sip_new(), SIP_PAGE2_OUTGOING_CALL, and username.
15388 { 15389 int oldformat; 15390 struct sip_pvt *p; 15391 struct ast_channel *tmpc = NULL; 15392 char *ext, *host; 15393 char tmp[256]; 15394 char *dest = data; 15395 15396 oldformat = format; 15397 if (!(format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1))) { 15398 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)); 15399 *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; /* Can't find codec to connect to host */ 15400 return NULL; 15401 } 15402 if (option_debug) 15403 ast_log(LOG_DEBUG, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat)); 15404 15405 if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE))) { 15406 ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", (char *)data); 15407 *cause = AST_CAUSE_SWITCH_CONGESTION; 15408 return NULL; 15409 } 15410 15411 ast_set_flag(&p->flags[1], SIP_PAGE2_OUTGOING_CALL); 15412 15413 if (!(p->options = ast_calloc(1, sizeof(*p->options)))) { 15414 sip_destroy(p); 15415 ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n"); 15416 *cause = AST_CAUSE_SWITCH_CONGESTION; 15417 return NULL; 15418 } 15419 15420 ast_copy_string(tmp, dest, sizeof(tmp)); 15421 host = strchr(tmp, '@'); 15422 if (host) { 15423 *host++ = '\0'; 15424 ext = tmp; 15425 } else { 15426 ext = strchr(tmp, '/'); 15427 if (ext) 15428 *ext++ = '\0'; 15429 host = tmp; 15430 } 15431 15432 if (create_addr(p, host)) { 15433 *cause = AST_CAUSE_UNREGISTERED; 15434 if (option_debug > 2) 15435 ast_log(LOG_DEBUG, "Cant create SIP call - target device not registred\n"); 15436 sip_destroy(p); 15437 return NULL; 15438 } 15439 if (ast_strlen_zero(p->peername) && ext) 15440 ast_string_field_set(p, peername, ext); 15441 /* Recalculate our side, and recalculate Call ID */ 15442 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 15443 p->ourip = __ourip; 15444 build_via(p); 15445 build_callid_pvt(p); 15446 15447 /* We have an extension to call, don't use the full contact here */ 15448 /* This to enable dialing registered peers with extension dialling, 15449 like SIP/peername/extension 15450 SIP/peername will still use the full contact */ 15451 if (ext) { 15452 ast_string_field_set(p, username, ext); 15453 ast_string_field_free(p, fullcontact); 15454 } 15455 #if 0 15456 printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host); 15457 #endif 15458 p->prefcodec = oldformat; /* Format for this call */ 15459 ast_mutex_lock(&p->lock); 15460 tmpc = sip_new(p, AST_STATE_DOWN, host); /* Place the call */ 15461 ast_mutex_unlock(&p->lock); 15462 if (!tmpc) 15463 sip_destroy(p); 15464 ast_update_use_count(); 15465 restart_monitor(); 15466 return tmpc; 15467 }
| static int sip_reregister | ( | void * | data | ) | [static] |
Update registration with SIP Proxy.
Definition at line 7143 of file chan_sip.c.
References __sip_do_register(), append_history, ast_log(), ast_test_flag, ASTOBJ_REF, ASTOBJ_UNREF, sip_registry::call, sip_registry::expire, sip_pvt::flags, LOG_NOTICE, SIP_NO_HISTORY, sip_registry_destroy(), and sipdebug.
Referenced by handle_response_register(), and sip_send_all_registers().
07144 { 07145 /* if we are here, we know that we need to reregister. */ 07146 struct sip_registry *r= ASTOBJ_REF((struct sip_registry *) data); 07147 07148 /* if we couldn't get a reference to the registry object, punt */ 07149 if (!r) 07150 return 0; 07151 07152 if (r->call && !ast_test_flag(&r->call->flags[0], SIP_NO_HISTORY)) 07153 append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname); 07154 /* Since registry's are only added/removed by the the monitor thread, this 07155 may be overkill to reference/dereference at all here */ 07156 if (sipdebug) 07157 ast_log(LOG_NOTICE, " -- Re-registration for %s@%s\n", r->username, r->hostname); 07158 07159 r->expire = -1; 07160 __sip_do_register(r); 07161 ASTOBJ_UNREF(r, sip_registry_destroy); 07162 return 0; 07163 }
| 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 4049 of file chan_sip.c.
References ast_dsp_process(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_null_frame, ast_rtcp_read(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_udptl_read(), f, ast_channel::fdno, sip_pvt::flags, sip_pvt::jointcapability, LOG_DEBUG, ast_channel::nativeformats, option_debug, sip_pvt::owner, ast_channel::readformat, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_PAGE2_T38SUPPORT_UDPTL, sip_pvt::t38, t38properties::t38support, sip_pvt::udptl, sip_pvt::vad, sip_pvt::vrtp, and ast_channel::writeformat.
Referenced by sip_read().
04050 { 04051 /* Retrieve audio/etc from channel. Assumes p->lock is already held. */ 04052 struct ast_frame *f; 04053 04054 if (!p->rtp) { 04055 /* We have no RTP allocated for this channel */ 04056 return &ast_null_frame; 04057 } 04058 04059 switch(ast->fdno) { 04060 case 0: 04061 f = ast_rtp_read(p->rtp); /* RTP Audio */ 04062 break; 04063 case 1: 04064 f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */ 04065 break; 04066 case 2: 04067 f = ast_rtp_read(p->vrtp); /* RTP Video */ 04068 break; 04069 case 3: 04070 f = ast_rtcp_read(p->vrtp); /* RTCP Control Channel for video */ 04071 break; 04072 case 5: 04073 f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ 04074 break; 04075 default: 04076 f = &ast_null_frame; 04077 } 04078 /* Don't forward RFC2833 if we're not supposed to */ 04079 if (f && (f->frametype == AST_FRAME_DTMF) && 04080 (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) 04081 return &ast_null_frame; 04082 04083 /* We already hold the channel lock */ 04084 if (!p->owner || f->frametype != AST_FRAME_VOICE) 04085 return f; 04086 04087 if (f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) { 04088 if (!(f->subclass & p->jointcapability)) { 04089 if (option_debug) { 04090 ast_log(LOG_DEBUG, "Bogus frame of format '%s' received from '%s'!\n", 04091 ast_getformatname(f->subclass), p->owner->name); 04092 } 04093 return &ast_null_frame; 04094 } 04095 if (option_debug) 04096 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 04097 p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass; 04098 ast_set_read_format(p->owner, p->owner->readformat); 04099 ast_set_write_format(p->owner, p->owner->writeformat); 04100 } 04101 04102 if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) { 04103 f = ast_dsp_process(p->owner, p->vad, f); 04104 if (f && f->frametype == AST_FRAME_DTMF) { 04105 if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') { 04106 if (option_debug) 04107 ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name); 04108 *faxdetect = 1; 04109 } else if (option_debug) { 04110 ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass); 04111 } 04112 } 04113 } 04114 04115 return f; 04116 }
| static void sip_scheddestroy | ( | struct sip_pvt * | p, | |
| int | ms | |||
| ) | [static] |
Schedule destruction of SIP dialog.
Definition at line 2027 of file chan_sip.c.
References __sip_autodestruct(), append_history, ast_sched_add(), ast_sched_del(), ast_test_flag, ast_verbose(), sip_pvt::flags, sip_pvt::method, sched, sip_debug_test_pvt(), sip_methods, SIP_NO_HISTORY, cfsip_methods::text, and sip_pvt::timer_t1.
Referenced by __sip_autodestruct(), cb_extensionstate(), check_auth(), check_pendings(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_notify(), sip_send_mwi_to_peer(), and sip_sipredirect().
02028 { 02029 if (ms < 0) { 02030 if (p->timer_t1 == 0) 02031 p->timer_t1 = 500; /* Set timer T1 if not set (RFC 3261) */ 02032 ms = p->timer_t1 * 64; 02033 } 02034 if (sip_debug_test_pvt(p)) 02035 ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text); 02036 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 02037 append_history(p, "SchedDestroy", "%d ms", ms); 02038 02039 if (p->autokillid > -1) 02040 ast_sched_del(sched, p->autokillid); 02041 p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p); 02042 }
| static void sip_send_all_registers | ( | void | ) | [static] |
Send all known registrations.
Definition at line 17194 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().
17195 { 17196 int ms; 17197 int regspacing; 17198 if (!regobjs) 17199 return; 17200 regspacing = default_expiry * 1000/regobjs; 17201 if (regspacing > 100) 17202 regspacing = 100; 17203 ms = regspacing; 17204 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 17205 ASTOBJ_WRLOCK(iterator); 17206 if (iterator->expire > -1) 17207 ast_sched_del(sched, iterator->expire); 17208 ms += regspacing; 17209 iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator); 17210 ASTOBJ_UNLOCK(iterator); 17211 } while (0) 17212 ); 17213 }
| 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 14957 of file chan_sip.c.
References __ourip, ast_app_inboxcount(), ast_set_flag, ast_sip_ouraddrfor(), build_callid_pvt(), build_via(), create_addr_from_peer(), 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().
14958 { 14959 /* Called with peerl lock, but releases it */ 14960 struct sip_pvt *p; 14961 int newmsgs, oldmsgs; 14962 14963 /* Check for messages */ 14964 ast_app_inboxcount(peer->mailbox, &newmsgs, &oldmsgs); 14965 14966 peer->lastmsgcheck = time(NULL); 14967 14968 /* Return now if it's the same thing we told them last time */ 14969 if (((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)) == peer->lastmsgssent) { 14970 return 0; 14971 } 14972 14973 14974 peer->lastmsgssent = ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)); 14975 14976 if (peer->mwipvt) { 14977 /* Base message on subscription */ 14978 p = peer->mwipvt; 14979 } else { 14980 /* Build temporary dialog for this message */ 14981 if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) 14982 return -1; 14983 if (create_addr_from_peer(p, peer)) { 14984 /* Maybe they're not registered, etc. */ 14985 sip_destroy(p); 14986 return 0; 14987 } 14988 /* Recalculate our side, and recalculate Call ID */ 14989 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 14990 p->ourip = __ourip; 14991 build_via(p); 14992 build_callid_pvt(p); 14993 /* Destroy this session after 32 secs */ 14994 sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); 14995 } 14996 /* Send MWI */ 14997 ast_set_flag(&p->flags[0], SIP_OUTGOING); 14998 transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten); 14999 return 0; 15000 }
| static int sip_senddigit_begin | ( | struct ast_channel * | ast, | |
| char | digit | |||
| ) | [static] |
Definition at line 3597 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.
03598 { 03599 struct sip_pvt *p = ast->tech_pvt; 03600 int res = 0; 03601 03602 ast_mutex_lock(&p->lock); 03603 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03604 case SIP_DTMF_INBAND: 03605 res = -1; /* Tell Asterisk to generate inband indications */ 03606 break; 03607 case SIP_DTMF_RFC2833: 03608 if (p->rtp) 03609 ast_rtp_senddigit_begin(p->rtp, digit); 03610 break; 03611 default: 03612 break; 03613 } 03614 ast_mutex_unlock(&p->lock); 03615 03616 return res; 03617 }
| 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 3621 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().
03622 { 03623 struct sip_pvt *p = ast->tech_pvt; 03624 int res = 0; 03625 03626 ast_mutex_lock(&p->lock); 03627 switch (ast_test_flag(&p->flags[0], SIP_DTMF)) { 03628 case SIP_DTMF_INFO: 03629 transmit_info_with_digit(p, digit, duration); 03630 break; 03631 case SIP_DTMF_RFC2833: 03632 if (p->rtp) 03633 ast_rtp_senddigit_end(p->rtp, digit); 03634 break; 03635 case SIP_DTMF_INBAND: 03636 res = -1; /* Tell Asterisk to stop inband indications */ 03637 break; 03638 } 03639 ast_mutex_unlock(&p->lock); 03640 03641 return res; 03642 }
| 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 2270 of file chan_sip.c.
References ast_strlen_zero(), ast_verbose(), debug, sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().
02271 { 02272 struct sip_pvt *p = ast->tech_pvt; 02273 int debug = sip_debug_test_pvt(p); 02274 02275 if (debug) 02276 ast_verbose("Sending text %s on %s\n", text, ast->name); 02277 if (!p) 02278 return -1; 02279 if (ast_strlen_zero(text)) 02280 return 0; 02281 if (debug) 02282 ast_verbose("Really sending text %s on %s\n", text, ast->name); 02283 transmit_message_with_text(p, text); 02284 return 0; 02285 }
| 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 16934 of file chan_sip.c.
References ast_channel::_state, append_history, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_get_peer(), ast_set_flag, AST_STATE_UP, ast_test_flag, sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, SIP_ALREADYGONE, SIP_CAN_REINVITE_NAT, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_NO_HISTORY, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), sip_pvt::vredirip, and sip_pvt::vrtp.
16935 { 16936 struct sip_pvt *p; 16937 int changed = 0; 16938 16939 p = chan->tech_pvt; 16940 if (!p) 16941 return -1; 16942 16943 /* Disable early RTP bridge */ 16944 if (chan->_state != AST_STATE_UP && !global_directrtpsetup) /* We are in early state */ 16945 return 0; 16946 16947 ast_mutex_lock(&p->lock); 16948 if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { 16949 /* If we're destroyed, don't bother */ 16950 ast_mutex_unlock(&p->lock); 16951 return 0; 16952 } 16953 16954 /* if this peer cannot handle reinvites of the media stream to devices 16955 that are known to be behind a NAT, then stop the process now 16956 */ 16957 if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) { 16958 ast_mutex_unlock(&p->lock); 16959 return 0; 16960 } 16961 16962 if (rtp) { 16963 changed |= ast_rtp_get_peer(rtp, &p->redirip); 16964 } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) { 16965 memset(&p->redirip, 0, sizeof(p->redirip)); 16966 changed = 1; 16967 } 16968 if (vrtp) { 16969 changed |= ast_rtp_get_peer(vrtp, &p->vredirip); 16970 } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) { 16971 memset(&p->vredirip, 0, sizeof(p->vredirip)); 16972 changed = 1; 16973 } 16974 if (codecs && (p->redircodecs != codecs)) { 16975 p->redircodecs = codecs; 16976 changed = 1; 16977 } 16978 if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 16979 if (chan->_state != AST_STATE_UP) { /* We are in early state */ 16980 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 16981 append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal."); 16982 if (option_debug) 16983 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)); 16984 } else if (!p->pendinginvite) { /* We are up, and have no outstanding invite */ 16985 if (option_debug > 2) { 16986 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)); 16987 } 16988 transmit_reinvite_with_sdp(p); 16989 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 16990 if (option_debug > 2) { 16991 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)); 16992 } 16993 /* We have a pending Invite. Send re-invite when we're done with the invite */ 16994 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 16995 } 16996 } 16997 /* Reset lastrtprx timer */ 16998 p->lastrtprx = p->lastrtptx = time(NULL); 16999 ast_mutex_unlock(&p->lock); 17000 return 0; 17001 }
| static int sip_set_udptl_peer | ( | struct ast_channel * | chan, | |
| struct ast_udptl * | udptl | |||
| ) | [static] |
Definition at line 16761 of file chan_sip.c.
References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_udptl_get_peer(), sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::lock, LOG_DEBUG, sip_pvt::ourip, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_t38_sdp(), sip_pvt::udptl, and sip_pvt::udptlredirip.
16762 { 16763 struct sip_pvt *p; 16764 16765 p = chan->tech_pvt; 16766 if (!p) 16767 return -1; 16768 ast_mutex_lock(&p->lock); 16769 if (udptl) 16770 ast_udptl_get_peer(udptl, &p->udptlredirip); 16771 else 16772 memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); 16773 if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) { 16774 if (!p->pendinginvite) { 16775 if (option_debug > 2) { 16776 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); 16777 } 16778 transmit_reinvite_with_t38_sdp(p); 16779 } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { 16780 if (option_debug > 2) { 16781 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); 16782 } 16783 ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); 16784 } 16785 } 16786 /* Reset lastrtprx timer */ 16787 p->lastrtprx = p->lastrtptx = time(NULL); 16788 ast_mutex_unlock(&p->lock); 16789 return 0; 16790 }
| static int sip_show_channel | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Show details of one active dialog.
Definition at line 10637 of file chan_sip.c.
References sip_pvt::allowtransfer, ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_mutex_lock(), ast_strlen_zero(), ast_test_flag, sip_pvt::capability, dtmfmode2str(), sip_pvt::flags, sip_route::hop, iflist, sip_pvt::jointcapability, sip_pvt::lastmsg, len, sip_pvt::maxcallbitrate, nat2str(), ast_channel::nativeformats, sip_pvt::next, sip_pvt::noncodeccapability, NONE, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::recv, sip_pvt::redirip, RESULT_SHOWUSAGE, sip_pvt::route, sip_pvt::sa, SIP_DTMF, SIP_NAT, SIP_NEEDDESTROY, sip_options, SIP_OUTGOING, SIP_PROMISCREDIR, sip_pvt::sipoptions, sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, text, and transfermode2str().
10638 { 10639 struct sip_pvt *cur; 10640 size_t len; 10641 int found = 0; 10642 10643 if (argc != 4) 10644 return RESULT_SHOWUSAGE; 10645 len = strlen(argv[3]); 10646 ast_mutex_lock(&iflock); 10647 for (cur = iflist; cur; cur = cur->next) { 10648 if (!strncasecmp(cur->callid, argv[3], len)) { 10649 char formatbuf[BUFSIZ/2]; 10650 ast_cli(fd,"\n"); 10651 if (cur->subscribed != NONE) 10652 ast_cli(fd, " * Subscription (type: %s)\n", subscription_type2str(cur->subscribed)); 10653 else 10654 ast_cli(fd, " * SIP Call\n"); 10655 ast_cli(fd, " Curr. trans. direction: %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming"); 10656 ast_cli(fd, " Call-ID: %s\n", cur->callid); 10657 ast_cli(fd, " Owner channel ID: %s\n", cur->owner ? cur->owner->name : "<none>"); 10658 ast_cli(fd, " Our Codec Capability: %d\n", cur->capability); 10659 ast_cli(fd, " Non-Codec Capability (DTMF): %d\n", cur->noncodeccapability); 10660 ast_cli(fd, " Their Codec Capability: %d\n", cur->peercapability); 10661 ast_cli(fd, " Joint Codec Capability: %d\n", cur->jointcapability); 10662 ast_cli(fd, " Format: %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) ); 10663 ast_cli(fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate); 10664 ast_cli(fd, " Theoretical Address: %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port)); 10665 ast_cli(fd, " Received Address: %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port)); 10666 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer)); 10667 ast_cli(fd, " NAT Support: %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT))); 10668 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)" ); 10669 ast_cli(fd, " Our Tag: %s\n", cur->tag); 10670 ast_cli(fd, " Their Tag: %s\n", cur->theirtag); 10671 ast_cli(fd, " SIP User agent: %s\n", cur->useragent); 10672 if (!ast_strlen_zero(cur->username)) 10673 ast_cli(fd, " Username: %s\n", cur->username); 10674 if (!ast_strlen_zero(cur->peername)) 10675 ast_cli(fd, " Peername: %s\n", cur->peername); 10676 if (!ast_strlen_zero(cur->uri)) 10677 ast_cli(fd, " Original uri: %s\n", cur->uri); 10678 if (!ast_strlen_zero(cur->cid_num)) 10679 ast_cli(fd, " Caller-ID: %s\n", cur->cid_num); 10680 ast_cli(fd, " Need Destroy: %d\n", ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY)); 10681 ast_cli(fd, " Last Message: %s\n", cur->lastmsg); 10682 ast_cli(fd, " Promiscuous Redir: %s\n", ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 10683 ast_cli(fd, " Route: %s\n", cur->route ? cur->route->hop : "N/A"); 10684 ast_cli(fd, " DTMF Mode: %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF))); 10685 ast_cli(fd, " SIP Options: "); 10686 if (cur->sipoptions) { 10687 int x; 10688 for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) { 10689 if (cur->sipoptions & sip_options[x].id) 10690 ast_cli(fd, "%s ", sip_options[x].text); 10691 } 10692 } else 10693 ast_cli(fd, "(none)\n"); 10694 ast_cli(fd, "\n\n"); 10695 found++; 10696 } 10697 } 10698 ast_mutex_unlock(&iflock); 10699 if (!found) 10700 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 10701 return RESULT_SUCCESS; 10702 }
| static int sip_show_channels | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Show active SIP channels.
Definition at line 10435 of file chan_sip.c.
References __sip_show_channels().
10436 { 10437 return __sip_show_channels(fd, argc, argv, 0); 10438 }
| static int sip_show_domains | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
CLI command to list local domains.
Definition at line 9941 of file chan_sip.c.
References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, domain::context, domain::domain, domain_mode_to_text(), FORMAT, domain::mode, RESULT_SUCCESS, and S_OR.
09942 { 09943 struct domain *d; 09944 #define FORMAT "%-40.40s %-20.20s %-16.16s\n" 09945 09946 if (AST_LIST_EMPTY(&domain_list)) { 09947 ast_cli(fd, "SIP Domain support not enabled.\n\n"); 09948 return RESULT_SUCCESS; 09949 } else { 09950 ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by"); 09951 AST_LIST_LOCK(&domain_list); 09952 AST_LIST_TRAVERSE(&domain_list, d, list) 09953 ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"), 09954 domain_mode_to_text(d->mode)); 09955 AST_LIST_UNLOCK(&domain_list); 09956 ast_cli(fd, "\n"); 09957 return RESULT_SUCCESS; 09958 } 09959 }
| static int sip_show_history | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Show history details of one dialog.
Definition at line 10705 of file chan_sip.c.
References ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock(), sip_pvt::history, iflist, len, sip_pvt::next, NONE, RESULT_SHOWUSAGE, and sip_pvt::subscribed.
10706 { 10707 struct sip_pvt *cur; 10708 size_t len; 10709 int found = 0; 10710 10711 if (argc != 4) 10712 return RESULT_SHOWUSAGE; 10713 if (!recordhistory) 10714 ast_cli(fd, "\n***Note: History recording is currently DISABLED. Use 'sip history' to ENABLE.\n"); 10715 len = strlen(argv[3]); 10716 ast_mutex_lock(&iflock); 10717 for (cur = iflist; cur; cur = cur->next) { 10718 if (!strncasecmp(cur->callid, argv[3], len)) { 10719 struct sip_history *hist; 10720 int x = 0; 10721 10722 ast_cli(fd,"\n"); 10723 if (cur->subscribed != NONE) 10724 ast_cli(fd, " * Subscription\n"); 10725 else 10726 ast_cli(fd, " * SIP Call\n"); 10727 if (cur->history) 10728 AST_LIST_TRAVERSE(cur->history, hist, list) 10729 ast_cli(fd, "%d. %s\n", ++x, hist->event); 10730 if (x == 0) 10731 ast_cli(fd, "Call '%s' has no history\n", cur->callid); 10732 found++; 10733 } 10734 } 10735 ast_mutex_unlock(&iflock); 10736 if (!found) 10737 ast_cli(fd, "No such SIP Call ID starting with '%s'\n", argv[3]); 10738 return RESULT_SUCCESS; 10739 }
| 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 9366 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, FALSE, FORMAT, FORMAT2, peerl, RESULT_SHOWUSAGE, RESULT_SUCCESS, TRUE, and userl.
09367 { 09368 #define FORMAT "%-25.25s %-15.15s %-15.15s \n" 09369 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n" 09370 char ilimits[40]; 09371 char iused[40]; 09372 int showall = FALSE; 09373 09374 if (argc < 3) 09375 return RESULT_SHOWUSAGE; 09376 09377 if (argc == 4 && !strcmp(argv[3],"all")) 09378 showall = TRUE; 09379 09380 ast_cli(fd, FORMAT, "* User name", "In use", "Limit"); 09381 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09382 ASTOBJ_RDLOCK(iterator); 09383 if (iterator->call_limit) 09384 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09385 else 09386 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09387 snprintf(iused, sizeof(iused), "%d", iterator->inUse); 09388 if (showall || iterator->call_limit) 09389 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09390 ASTOBJ_UNLOCK(iterator); 09391 } while (0) ); 09392 09393 ast_cli(fd, FORMAT, "* Peer name", "In use", "Limit"); 09394 09395 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 09396 ASTOBJ_RDLOCK(iterator); 09397 if (iterator->call_limit) 09398 snprintf(ilimits, sizeof(ilimits), "%d", iterator->call_limit); 09399 else 09400 ast_copy_string(ilimits, "N/A", sizeof(ilimits)); 09401 snprintf(iused, sizeof(iused), "%d/%d", iterator->inUse, iterator->inRinging); 09402 if (showall || iterator->call_limit) 09403 ast_cli(fd, FORMAT2, iterator->name, iused, ilimits); 09404 ASTOBJ_UNLOCK(iterator); 09405 } while (0) ); 09406 09407 return RESULT_SUCCESS; 09408 #undef FORMAT 09409 #undef FORMAT2 09410 }
| static int sip_show_objects | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
List all allocated SIP Objects (realtime or static).
Definition at line 9687 of file chan_sip.c.
References ast_cli(), ASTOBJ_CONTAINER_DUMP, peerl, regl, RESULT_SHOWUSAGE, RESULT_SUCCESS, and userl.
09688 { 09689 char tmp[256]; 09690 if (argc != 3) 09691 return RESULT_SHOWUSAGE; 09692 ast_cli(fd, "-= User objects: %d static, %d realtime =-\n\n", suserobjs, ruserobjs); 09693 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &userl); 09694 ast_cli(fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs); 09695 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), &peerl); 09696 ast_cli(fd, "-= Registry objects: %d =-\n\n", regobjs); 09697 ASTOBJ_CONTAINER_DUMP(fd, tmp, sizeof(tmp), ®l); 09698 return RESULT_SUCCESS; 09699 }
| static int sip_show_peer | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Show one peer in detail.
Definition at line 9993 of file chan_sip.c.
References _sip_show_peer().
09994 { 09995 return _sip_show_peer(0, fd, NULL, NULL, argc, (const char **) argv); 09996 }
| static int sip_show_peers | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
CLI Show Peers command.
Definition at line 9543 of file chan_sip.c.
References _sip_show_peers().
09544 { 09545 return _sip_show_peers(fd, NULL, NULL, NULL, argc, (const char **) argv); 09546 }
| static int sip_show_registry | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Show SIP Registry (registrations with other SIP proxies.
Definition at line 10266 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.
10267 { 10268 #define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-25.25s\n" 10269 #define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-25.25s\n" 10270 char host[80]; 10271 char tmpdat[256]; 10272 struct tm tm; 10273 10274 10275 if (argc != 3) 10276 return RESULT_SHOWUSAGE; 10277 ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Reg.Time"); 10278 ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { 10279 ASTOBJ_RDLOCK(iterator); 10280 snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT); 10281 if (iterator->regtime) { 10282 ast_localtime(&iterator->regtime, &tm, NULL); 10283 strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm); 10284 } else { 10285 tmpdat[0] = 0; 10286 } 10287 ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat); 10288 ASTOBJ_UNLOCK(iterator); 10289 } while(0)); 10290 return RESULT_SUCCESS; 10291 #undef FORMAT 10292 #undef FORMAT2 10293 }
| static int sip_show_settings | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
List global settings for the SIP channel.
Definition at line 10296 of file chan_sip.c.
References ast_check_realtime(), ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), AST_JB_ENABLED, AST_JB_FORCED, AST_JB_LOG, AST_LIST_EMPTY, ast_test_flag, ast_tos2str(), authl, bindaddr, default_prefs, dtmfmode2str(), global_flags, global_jbconf, ast_jb_conf::impl, ast_jb_conf::max_size, nat2str(), print_codec_to_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_jb_conf::resync_threshold, S_OR, SIP_DTMF, SIP_NAT, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTSAVE_SYSNAME, SIP_PAGE2_RTUPDATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, SIP_USECLIENTCODE, SIP_USEREQPHONE, and transfermode2str().
10297 { 10298 int realtimepeers; 10299 int realtimeusers; 10300 char codec_buf[BUFSIZ]; 10301 10302 realtimepeers = ast_check_realtime("sippeers"); 10303 realtimeusers = ast_check_realtime("sipusers"); 10304 10305 if (argc != 3) 10306 return RESULT_SHOWUSAGE; 10307 ast_cli(fd, "\n\nGlobal Settings:\n"); 10308 ast_cli(fd, "----------------\n"); 10309 ast_cli(fd, " SIP Port: %d\n", ntohs(bindaddr.sin_port)); 10310 ast_cli(fd, " Bindaddress: %s\n", ast_inet_ntoa(bindaddr.sin_addr)); 10311 ast_cli(fd, " Videosupport: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No"); 10312 ast_cli(fd, " AutoCreatePeer: %s\n", autocreatepeer ? "Yes" : "No"); 10313 ast_cli(fd, " Allow unknown access: %s\n", global_allowguest ? "Yes" : "No"); 10314 ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No"); 10315 ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No"); 10316 ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global_flags[0], SIP_PROMISCREDIR) ? "Yes" : "No"); 10317 ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes"); 10318 ast_cli(fd, " Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No"); 10319 ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global_flags[0], SIP_USEREQPHONE) ? "Yes" : "No"); 10320 ast_cli(fd, " Our auth realm %s\n", global_realm); 10321 ast_cli(fd, " Realm. auth: %s\n", authl ? "Yes": "No"); 10322 ast_cli(fd, " Always auth rejects: %s\n", global_alwaysauthreject ? "Yes" : "No"); 10323 ast_cli(fd, " Call limit peers only: %s\n", global_limitonpeers ? "Yes" : "No"); 10324 ast_cli(fd, " Direct RTP setup: %s\n", global_directrtpsetup ? "Yes" : "No"); 10325 ast_cli(fd, " User Agent: %s\n", global_useragent); 10326 ast_cli(fd, " MWI checking interval: %d secs\n", global_mwitime); 10327 ast_cli(fd, " Reg. context: %s\n", S_OR(global_regcontext, "(not set)")); 10328 ast_cli(fd, " Caller ID: %s\n", default_callerid); 10329 ast_cli(fd, " From: Domain: %s\n", default_fromdomain); 10330 ast_cli(fd, " Record SIP history: %s\n", recordhistory ? "On" : "Off"); 10331 ast_cli(fd, " Call Events: %s\n", global_callevents ? "On" : "Off"); 10332 ast_cli(fd, " IP ToS SIP: %s\n", ast_tos2str(global_tos_sip)); 10333 ast_cli(fd, " IP ToS RTP audio: %s\n", ast_tos2str(global_tos_audio)); 10334 ast_cli(fd, " IP ToS RTP video: %s\n", ast_tos2str(global_tos_video)); 10335 ast_cli(fd, " T38 fax pt UDPTL: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_UDPTL) ? "Yes" : "No"); 10336 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS 10337 ast_cli(fd, " T38 fax pt RTP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_RTP) ? "Yes" : "No"); 10338 ast_cli(fd, " T38 fax pt TCP: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT_TCP) ? "Yes" : "No"); 10339 #endif 10340 ast_cli(fd, " RFC2833 Compensation: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE) ? "Yes" : "No"); 10341 ast_cli(fd, " Jitterbuffer enabled: %s\n", ast_test_flag(&global_jbconf, AST_JB_ENABLED) ? "Yes" : "No"); 10342 ast_cli(fd, " Jitterbuffer forced: %s\n", ast_test_flag(&global_jbconf, AST_JB_FORCED) ? "Yes" : "No"); 10343 ast_cli(fd, " Jitterbuffer max size: %ld\n", global_jbconf.max_size); 10344 ast_cli(fd, " Jitterbuffer resync: %ld\n", global_jbconf.resync_threshold); 10345 ast_cli(fd, " Jitterbuffer impl: %s\n", global_jbconf.impl); 10346 ast_cli(fd, " Jitterbuffer log: %s\n", ast_test_flag(&global_jbconf, AST_JB_LOG) ? "Yes" : "No"); 10347 if (!realtimepeers && !realtimeusers) 10348 ast_cli(fd, " SIP realtime: Disabled\n" ); 10349 else 10350 ast_cli(fd, " SIP realtime: Enabled\n" ); 10351 10352 ast_cli(fd, "\nGlobal Signalling Settings:\n"); 10353 ast_cli(fd, "---------------------------\n"); 10354 ast_cli(fd, " Codecs: "); 10355 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability); 10356 ast_cli(fd, "%s\n", codec_buf); 10357 ast_cli(fd, " Codec Order: "); 10358 print_codec_to_cli(fd, &default_prefs); 10359 ast_cli(fd, "\n"); 10360 ast_cli(fd, " T1 minimum: %d\n", global_t1min); 10361 ast_cli(fd, " Relax DTMF: %s\n", global_relaxdtmf ? "Yes" : "No"); 10362 ast_cli(fd, " Compact SIP headers: %s\n", compactheaders ? "Yes" : "No"); 10363 ast_cli(fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" ); 10364 ast_cli(fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" ); 10365 ast_cli(fd, " RTP Hold Timeout: %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)"); 10366 ast_cli(fd, " MWI NOTIFY mime type: %s\n", default_notifymime); 10367 ast_cli(fd, " DNS SRV lookup: %s\n", srvlookup ? "Yes" : "No"); 10368 ast_cli(fd, " Pedantic SIP support: %s\n", pedanticsipchecking ? "Yes" : "No"); 10369 ast_cli(fd, " Reg. min duration %d secs\n", min_expiry); 10370 ast_cli(fd, " Reg. max duration: %d secs\n", max_expiry); 10371 ast_cli(fd, " Reg. default duration: %d secs\n", default_expiry); 10372 ast_cli(fd, " Outbound reg. timeout: %d secs\n", global_reg_timeout); 10373 ast_cli(fd, " Outbound reg. attempts: %d\n", global_regattempts_max); 10374 ast_cli(fd, " Notify ringing state: %s\n", global_notifyringing ? "Yes" : "No"); 10375 ast_cli(fd, " Notify hold state: %s\n", global_notifyhold ? "Yes" : "No"); 10376 ast_cli(fd, " SIP Transfer mode: %s\n", transfermode2str(global_allowtransfer)); 10377 ast_cli(fd, " Max Call Bitrate: %d kbps\r\n", default_maxcallbitrate); 10378 ast_cli(fd, " Auto-Framing: %s \r\n", global_autoframing ? "Yes" : "No"); 10379 ast_cli(fd, "\nDefault Settings:\n"); 10380 ast_cli(fd, "-----------------\n"); 10381 ast_cli(fd, " Context: %s\n", default_context); 10382 ast_cli(fd, " Nat: %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT))); 10383 ast_cli(fd, " DTMF: %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF))); 10384 ast_cli(fd, " Qualify: %d\n", default_qualify); 10385 ast_cli(fd, " Use ClientCode: %s\n", ast_test_flag(&global_flags[0], SIP_USECLIENTCODE) ? "Yes" : "No"); 10386 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" ); 10387 ast_cli(fd, " Language: %s\n", S_OR(default_language, "(Defaults to English)")); 10388 ast_cli(fd, " MOH Interpret: %s\n", default_mohinterpret); 10389 ast_cli(fd, " MOH Suggest: %s\n", default_mohsuggest); 10390 ast_cli(fd, " Voice Mail Extension: %s\n", default_vmexten); 10391 10392 10393 if (realtimepeers || realtimeusers) { 10394 ast_cli(fd, "\nRealtime SIP Settings:\n"); 10395 ast_cli(fd, "----------------------\n"); 10396 ast_cli(fd, " Realtime Peers: %s\n", realtimepeers ? "Yes" : "No"); 10397 ast_cli(fd, " Realtime Users: %s\n", realtimeusers ? "Yes" : "No"); 10398 ast_cli(fd, " Cache Friends: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? "Yes" : "No"); 10399 ast_cli(fd, " Update: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) ? "Yes" : "No"); 10400 ast_cli(fd, " Ignore Reg. Expire: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE) ? "Yes" : "No"); 10401 ast_cli(fd, " Save sys. name: %s\n", ast_test_flag(&global_flags[1], SIP_PAGE2_RTSAVE_SYSNAME) ? "Yes" : "No"); 10402 ast_cli(fd, " Auto Clear: %d\n", global_rtautoclear); 10403 } 10404 ast_cli(fd, "\n----\n"); 10405 return RESULT_SUCCESS; 10406 }
| static int sip_show_subscriptions | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Show active SIP subscriptions.
Definition at line 10441 of file chan_sip.c.
References __sip_show_channels().
10442 { 10443 return __sip_show_channels(fd, argc, argv, 1); 10444 }
| static int sip_show_user | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Show one user in detail.
Definition at line 10211 of file chan_sip.c.
References sip_user::accountcode, sip_user::allowtransfer, sip_user::amaflags, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_describe_caller_presentation(), ast_strlen_zero(), ASTOBJ_UNREF, sip_user::autoframing, sip_user::call_limit, sip_user::callgroup, sip_user::callingpres, sip_user::chanvars, sip_user::cid_name, sip_user::cid_num, sip_user::context, FALSE, find_user(), sip_user::ha, sip_user::language, sip_user::maxcallbitrate, sip_user::md5secret, ast_variable::name, ast_variable::next, sip_user::pickupgroup, sip_user::prefs, print_codec_to_cli(), print_group(), RESULT_SHOWUSAGE, RESULT_SUCCESS, sip_user::secret, sip_destroy_user(), transfermode2str(), TRUE, and ast_variable::value.
10212 { 10213 char cbuf[256]; 10214 struct sip_user *user; 10215 struct ast_variable *v; 10216 int load_realtime; 10217 10218 if (argc < 4) 10219 return RESULT_SHOWUSAGE; 10220 10221 /* Load from realtime storage? */ 10222 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE; 10223 10224 user = find_user(argv[3], load_realtime); 10225 if (user) { 10226 ast_cli(fd,"\n\n"); 10227 ast_cli(fd, " * Name : %s\n", user->name); 10228 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>"); 10229 ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>"); 10230 ast_cli(fd, " Context : %s\n", user->context); 10231 ast_cli(fd, " Language : %s\n", user->language); 10232 if (!ast_strlen_zero(user->accountcode)) 10233 ast_cli(fd, " Accountcode : %s\n", user->accountcode); 10234 ast_cli(fd, " AMA flags : %s\n", ast_cdr_flags2str(user->amaflags)); 10235 ast_cli(fd, " Transfer mode: %s\n", transfermode2str(user->allowtransfer)); 10236 ast_cli(fd, " MaxCallBR : %d kbps\n", user->maxcallbitrate); 10237 ast_cli(fd, " CallingPres : %s\n", ast_describe_caller_presentation(user->callingpres)); 10238 ast_cli(fd, " Call limit : %d\n", user->call_limit); 10239 ast_cli(fd, " Callgroup : "); 10240 print_group(fd, user->callgroup, 0); 10241 ast_cli(fd, " Pickupgroup : "); 10242 print_group(fd, user->pickupgroup, 0); 10243 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>")); 10244 ast_cli(fd, " ACL : %s\n", (user->ha?"Yes":"No")); 10245 ast_cli(fd, " Codec Order : ("); 10246 print_codec_to_cli(fd, &user->prefs); 10247 ast_cli(fd, ")\n"); 10248 10249 ast_cli(fd, " Auto-Framing: %s \n", user->autoframing ? "Yes" : "No"); 10250 if (user->chanvars) { 10251 ast_cli(fd, " Variables :\n"); 10252 for (v = user->chanvars ; v ; v = v->next) 10253 ast_cli(fd, " %s = %s\n", v->name, v->value); 10254 } 10255 ast_cli(fd,"\n"); 10256 ASTOBJ_UNREF(user,sip_destroy_user); 10257 } else { 10258 ast_cli(fd,"User %s not found.\n", argv[3]); 10259 ast_cli(fd,"\n"); 10260 } 10261 10262 return RESULT_SUCCESS; 10263 }
| static int sip_show_users | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
CLI Command 'SIP Show Users'.
Definition at line 9466 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.
09467 { 09468 regex_t regexbuf; 09469 int havepattern = FALSE; 09470 09471 #define FORMAT "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n" 09472 09473 switch (argc) { 09474 case 5: 09475 if (!strcasecmp(argv[3], "like")) { 09476 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 09477 return RESULT_SHOWUSAGE; 09478 havepattern = TRUE; 09479 } else 09480 return RESULT_SHOWUSAGE; 09481 case 3: 09482 break; 09483 default: 09484 return RESULT_SHOWUSAGE; 09485 } 09486 09487 ast_cli(fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT"); 09488 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 09489 ASTOBJ_RDLOCK(iterator); 09490 09491 if (havepattern && regexec(®exbuf, iterator->name, 0, NULL, 0)) { 09492 ASTOBJ_UNLOCK(iterator); 09493 continue; 09494 } 09495 09496 ast_cli(fd, FORMAT, iterator->name, 09497 iterator->secret, 09498 iterator->accountcode, 09499 iterator->context, 09500 iterator->ha ? "Yes" : "No", 09501 nat2str(ast_test_flag(&iterator->flags[0], SIP_NAT))); 09502 ASTOBJ_UNLOCK(iterator); 09503 } while (0) 09504 ); 09505 09506 if (havepattern) 09507 regfree(®exbuf); 09508 09509 return RESULT_SUCCESS; 09510 #undef FORMAT 09511 }
| static int sip_sipredirect | ( | struct sip_pvt * | p, | |
| const char * | dest | |||
| ) | [static] |
Transfer call before connect with a 302 redirect.
Definition at line 17114 of file chan_sip.c.
References ast_log(), ast_strdupa, ast_string_field_build, ast_strlen_zero(), get_header(), sip_pvt::initreq, LOG_ERROR, sip_scheddestroy(), strsep(), and transmit_response_reliable().
Referenced by sip_transfer().
17115 { 17116 char *cdest; 17117 char *extension, *host, *port; 17118 char tmp[80]; 17119 17120 cdest = ast_strdupa(dest); 17121 17122 extension = strsep(&cdest, "@"); 17123 host = strsep(&cdest, ":"); 17124 port = strsep(&cdest, ":"); 17125 if (ast_strlen_zero(extension)) { 17126 ast_log(LOG_ERROR, "Missing mandatory argument: extension\n"); 17127 return 0; 17128 } 17129 17130 /* we'll issue the redirect message here */ 17131 if (!host) { 17132 char *localtmp; 17133 ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp)); 17134 if (ast_strlen_zero(tmp)) { 17135 ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n"); 17136 return 0; 17137 } 17138 if ((localtmp = strstr(tmp, "sip:")) && (localtmp = strchr(localtmp, '@'))) { 17139 char lhost[80], lport[80]; 17140 memset(lhost, 0, sizeof(lhost)); 17141 memset(lport, 0, sizeof(lport)); 17142 localtmp++; 17143 /* This is okey because lhost and lport are as big as tmp */ 17144 sscanf(localtmp, "%[^<>:; ]:%[^<>:; ]", lhost, lport); 17145 if (ast_strlen_zero(lhost)) { 17146 ast_log(LOG_ERROR, "Can't find the host address\n"); 17147 return 0; 17148 } 17149 host = ast_strdupa(lhost); 17150 if (!ast_strlen_zero(lport)) { 17151 port = ast_strdupa(lport); 17152 } 17153 } 17154 } 17155 17156 ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : ""); 17157 transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq); 17158 17159 sip_scheddestroy(p, 32000); /* Make sure we stop send this reply. */ 17160 17161 return 0; 17162 }
| static int sip_transfer | ( | struct ast_channel * | ast, | |
| const char * | dest | |||
| ) | [static] |
Transfer SIP call.
Definition at line 3645 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().
03646 { 03647 struct sip_pvt *p = ast->tech_pvt; 03648 int res; 03649 03650 if (dest == NULL) /* functions below do not take a NULL */ 03651 dest = ""; 03652 ast_mutex_lock(&p->lock); 03653 if (ast->_state == AST_STATE_RING) 03654 res = sip_sipredirect(p, dest); 03655 else 03656 res = transmit_refer(p, dest); 03657 ast_mutex_unlock(&p->lock); 03658 return res; 03659 }
| static int sip_write | ( | struct ast_channel * | ast, | |
| struct ast_frame * | frame | |||
| ) | [static] |
Send frame to media channel (rtp).
Definition at line 3478 of file chan_sip.c.
References ast_channel::_state, ast_backtrace(), AST_FORMAT_AUDIO_MASK, ast_frame_dump(), AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), sip_pvt::flags, ast_frame::frametype, sip_pvt::initreq, sip_pvt::lastrtptx, sip_pvt::lock, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, sip_pvt::rtp, SIP_OUTGOING, SIP_PROGRESS_SENT, ast_frame::subclass, ast_channel::tech_pvt, transmit_response_with_sdp(), sip_pvt::udptl, sip_pvt::vrtp, ast_channel::writeformat, and XMIT_UNRELIABLE.
03479 { 03480 struct sip_pvt *p = ast->tech_pvt; 03481 int res = 0; 03482 03483 switch (frame->frametype) { 03484 case AST_FRAME_VOICE: 03485 if (!(frame->subclass & ast->nativeformats)) { 03486 char s1[512], s2[512], s3[512]; 03487 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n", 03488 frame->subclass, 03489 ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK), 03490 ast->nativeformats & AST_FORMAT_AUDIO_MASK, 03491 ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat), 03492 ast->readformat, 03493 ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat), 03494 ast->writeformat); 03495 ast_frame_dump(ast->name, frame, "<<"); 03496 ast_backtrace(); 03497 return 0; 03498 } 03499 if (p) { 03500 ast_mutex_lock(&p->lock); 03501 if (p->rtp) { 03502 /* If channel is not up, activate early media session */ 03503 if ((ast->_state != AST_STATE_UP) && 03504 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03505 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03506 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03507 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03508 } 03509 p->lastrtptx = time(NULL); 03510 res = ast_rtp_write(p->rtp, frame); 03511 } 03512 ast_mutex_unlock(&p->lock); 03513 } 03514 break; 03515 case AST_FRAME_VIDEO: 03516 if (p) { 03517 ast_mutex_lock(&p->lock); 03518 if (p->vrtp) { 03519 /* Activate video early media */ 03520 if ((ast->_state != AST_STATE_UP) && 03521 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && 03522 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 03523 transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE); 03524 ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); 03525 } 03526 p->lastrtptx = time(NULL); 03527 res = ast_rtp_write(p->vrtp, frame); 03528 } 03529 ast_mutex_unlock(&p->lock); 03530 } 03531 break; 03532 case AST_FRAME_IMAGE: 03533 return 0; 03534 break; 03535 case AST_FRAME_MODEM: 03536 if (p) { 03537 ast_mutex_lock(&p->lock); 03538 /* UDPTL requires two-way communication, so early media is not needed here. 03539 we simply forget the frames if we get modem frames before the bridge is up. 03540 Fax will re-transmit. 03541 */ 03542 if (p->udptl && ast->_state == AST_STATE_UP) 03543 res = ast_udptl_write(p->udptl, frame); 03544 ast_mutex_unlock(&p->lock); 03545 } 03546 break; 03547 default: 03548 ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype); 03549 return 0; 03550 } 03551 03552 return res; 03553 }
| static int sipsock_read | ( | int * | id, | |
| int | fd, | |||
| short | events, | |||
| void * | ignore | |||
| ) | [static] |
Read data from SIP socket.
Definition at line 14856 of file chan_sip.c.
References append_history, ast_channel_trylock, ast_channel_unlock, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_update_use_count(), ast_verbose(), find_call(), find_sip_method(), sip_pvt::flags, get_header(), handle_request(), len, sip_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, lws2sws(), option_debug, sip_pvt::owner, parse_request(), sip_pvt::recv, S_OR, SIP_ACK, sip_debug_test_addr(), SIP_NO_HISTORY, SIP_PKT_DEBUG, sipsock, and transmit_response().
Referenced by do_monitor().
14857 { 14858 struct sip_request req; 14859 struct sockaddr_in sin = { 0, }; 14860 struct sip_pvt *p; 14861 int res; 14862 socklen_t len = sizeof(sin); 14863 int nounlock; 14864 int recount = 0; 14865 int lockretry; 14866 14867 memset(&req, 0, sizeof(req)); 14868 res = recvfrom(sipsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 14869 if (res < 0) { 14870 #if !defined(__FreeBSD__) 14871 if (errno == EAGAIN) 14872 ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n"); 14873 else 14874 #endif 14875 if (errno != ECONNREFUSED) 14876 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 14877 return 1; 14878 } 14879 if (option_debug && res == sizeof(req.data)) { 14880 ast_log(LOG_DEBUG, "Received packet exceeds buffer. Data is possibly lost\n"); 14881 req.data[sizeof(req.data) - 1] = '\0'; 14882 } else 14883 req.data[res] = '\0'; 14884 req.len = res; 14885 if(sip_debug_test_addr(&sin)) /* Set the debug flag early on packet level */ 14886 ast_set_flag(&req, SIP_PKT_DEBUG); 14887 if (pedanticsipchecking) 14888 req.len = lws2sws(req.data, req.len); /* Fix multiline headers */ 14889 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 14890 ast_verbose("\n<--- SIP read from %s:%d --->\n%s\n<------------->\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), req.data); 14891 14892 parse_request(&req); 14893 req.method = find_sip_method(req.rlPart1); 14894 14895 if (ast_test_flag(&req, SIP_PKT_DEBUG)) 14896 ast_verbose("--- (%d headers %d lines)%s ---\n", req.headers, req.lines, (req.headers + req.lines == 0) ? " Nat keepalive" : ""); 14897 14898 if (req.headers < 2) /* Must have at least two headers */ 14899 return 1; 14900 14901 /* Process request, with netlock held, and with usual deadlock avoidance */ 14902 for (lockretry = 100; lockretry > 0; lockretry--) { 14903 ast_mutex_lock(&netlock); 14904 14905 /* Find the active SIP dialog or create a new one */ 14906 p = find_call(&req, &sin, req.method); /* returns p locked */ 14907 if (p == NULL) { 14908 if (option_debug) 14909 ast_log(LOG_DEBUG, "Invalid SIP message - rejected , no callid, len %d\n", req.len); 14910 ast_mutex_unlock(&netlock); 14911 return 1; 14912 } 14913 /* Go ahead and lock the owner if it has one -- we may need it */ 14914 /* becaues this is deadlock-prone, we need to try and unlock if failed */ 14915 if (!p->owner || !ast_channel_trylock(p->owner)) 14916 break; /* locking succeeded */ 14917 if (option_debug) 14918 ast_log(LOG_DEBUG, "Failed to grab owner channel lock, trying again. (SIP call %s)\n", p->callid); 14919 ast_mutex_unlock(&p->lock); 14920 ast_mutex_unlock(&netlock); 14921 /* Sleep for a very short amount of time */ 14922 usleep(1); 14923 } 14924 p->recv = sin; 14925 14926 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) /* This is a request or response, note what it was for */ 14927 append_history(p, "Rx", "%s / %s / %s", req.data, get_header(&req, "CSeq"), req.rlPart2); 14928 14929 if (!lockretry) { 14930 if (p->owner) 14931 ast_log(LOG_ERROR, "We could NOT get the channel lock for %s! \n", S_OR(p->owner->name, "- no channel name ??? - ")); 14932 ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid); 14933 if (req.method != SIP_ACK) 14934 transmit_response(p, "503 Server error", &req); /* We must respond according to RFC 3261 sec 12.2 */ 14935 /* XXX We could add retry-after to make sure they come back */ 14936 append_history(p, "LockFail", "Owner lock failed, transaction failed."); 14937 return 1; 14938 } 14939 nounlock = 0; 14940 if (handle_request(p, &req, &sin, &recount, &nounlock) == -1) { 14941 /* Request failed */ 14942 if (option_debug) 14943 ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>"); 14944 } 14945 14946 if (p->owner && !nounlock) 14947 ast_channel_unlock(p->owner); 14948 ast_mutex_unlock(&p->lock); 14949 ast_mutex_unlock(&netlock); 14950 if (recount) 14951 ast_update_use_count(); 14952 14953 return 1; 14954 }
| static void stop_media_flows | ( | struct sip_pvt * | p | ) | [static] |
Immediately stop RTP, VRTP and UDPTL as applicable.
Definition at line 12192 of file chan_sip.c.
References ast_rtp_stop(), ast_udptl_stop(), sip_pvt::rtp, sip_pvt::udptl, and sip_pvt::vrtp.
Referenced by handle_request_bye(), handle_request_cancel(), and handle_response().
12193 { 12194 /* Immediately stop RTP, VRTP and UDPTL as applicable */ 12195 if (p->rtp) 12196 ast_rtp_stop(p->rtp); 12197 if (p->vrtp) 12198 ast_rtp_stop(p->vrtp); 12199 if (p->udptl) 12200 ast_udptl_stop(p->udptl); 12201 }
| static const char * subscription_type2str | ( | enum subscriptiontype | subtype | ) | [static] |
Show subscription type in string format.
Definition at line 10409 of file chan_sip.c.
References subscription_types, and type.
Referenced by sip_show_channel().
10410 { 10411 int i; 10412 10413 for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) { 10414 if (subscription_types[i].type == subtype) { 10415 return subscription_types[i].text; 10416 } 10417 } 10418 return subscription_types[0].text; 10419 }
| static int t38_get_rate | ( | int | t38cap | ) | [static] |
Get Max T.38 Transmission rate from T38 capabilities.
Definition at line 5981 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().
05982 { 05983 int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400)); 05984 05985 if (maxrate & T38FAX_RATE_14400) { 05986 if (option_debug > 1) 05987 ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n"); 05988 return 14400; 05989 } else if (maxrate & T38FAX_RATE_12000) { 05990 if (option_debug > 1) 05991 ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n"); 05992 return 12000; 05993 } else if (maxrate & T38FAX_RATE_9600) { 05994 if (option_debug > 1) 05995 ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n"); 05996 return 9600; 05997 } else if (maxrate & T38FAX_RATE_7200) { 05998 if (option_debug > 1) 05999 ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n"); 06000 return 7200; 06001 } else if (maxrate & T38FAX_RATE_4800) { 06002 if (option_debug > 1) 06003 ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n"); 06004 return 4800; 06005 } else if (maxrate & T38FAX_RATE_2400) { 06006 if (option_debug > 1) 06007 ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n"); 06008 return 2400; 06009 } else { 06010 if (option_debug > 1) 06011 ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n"); 06012 return 0; 06013 } 06014 }
| static struct sip_peer * temp_peer | ( | const char * | name | ) | [static] |
Create temporary peer (used in autocreatepeer mode).
Definition at line 15924 of file chan_sip.c.
References ast_calloc, ast_set_flag, ASTOBJ_INIT, default_prefs, reg_source_db(), set_peer_defaults(), SIP_PAGE2_DYNAMIC, and SIP_PAGE2_SELFDESTRUCT.
Referenced by register_verify().
15925 { 15926 struct sip_peer *peer; 15927 15928 if (!(peer = ast_calloc(1, sizeof(*peer)))) 15929 return NULL; 15930 15931 apeerobjs++; 15932 ASTOBJ_INIT(peer); 15933 set_peer_defaults(peer); 15934 15935 ast_copy_string(peer->name, name, sizeof(peer->name)); 15936 15937 ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT); 15938 ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC); 15939 peer->prefs = default_prefs; 15940 reg_source_db(peer); 15941 15942 return peer; 15943 }
| static void temp_pvt_cleanup | ( | void * | ) | [static] |
Definition at line 5760 of file chan_sip.c.
References ast_string_field_free_pools, and free.
05761 { 05762 struct sip_pvt *p = data; 05763 05764 ast_string_field_free_pools(p); 05765 05766 free(data); 05767 }
| static char * transfermode2str | ( | enum transfermodes | mode | ) | const [static] |
Convert transfer mode to text string.
Definition at line 9413 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().
09414 { 09415 if (mode == TRANSFER_OPENFORALL) 09416 return "open"; 09417 else if (mode == TRANSFER_CLOSED) 09418 return "closed"; 09419 return "strict"; 09420 }
| 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 8255 of file chan_sip.c.
References ast_random(), ast_string_field_build, and transmit_response_with_auth().
Referenced by handle_request_invite(), handle_request_subscribe(), and register_verify().
08256 { 08257 ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */ 08258 transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0); 08259 }
| 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 7500 of file chan_sip.c.
References add_digit(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_senddigit_end().
07501 { 07502 struct sip_request req; 07503 07504 reqprep(&req, p, SIP_INFO, 0, 1); 07505 add_digit(&req, digit, duration); 07506 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07507 }
| static int transmit_info_with_vidupdate | ( | struct sip_pvt * | p | ) | [static] |
Send SIP INFO with video update request.
Definition at line 7510 of file chan_sip.c.
References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.
Referenced by sip_indicate().
07511 { 07512 struct sip_request req; 07513 07514 reqprep(&req, p, SIP_INFO, 0, 1); 07515 add_vidupdate(&req); 07516 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07517 }
| 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 6781 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_sdp(), add_t38_sdp(), sip_invite_param::addsipheaders, ALLOWED_METHODS, append_date(), AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_strdupa, ast_strlen_zero(), ast_udptl_offered_from_local(), ast_var_name(), ast_var_value(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::branch, build_via(), sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::lastinvite, LOG_DEBUG, LOG_WARNING, sip_request::method, sip_pvt::ocseq, option_debug, sip_pvt::options, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_to, sip_refer::referred_by, sip_refer::referred_by_name, sip_invite_param::replaces, reqprep(), sip_pvt::rtp, send_request(), SIP_REFER, sipdebug, t38properties::state, SUPPORTED_EXTENSIONS, sip_pvt::t38, T38_LOCAL_DIRECT, sip_pvt::udptl, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.
Referenced by do_proxy_auth(), sip_call(), and sip_poke_peer().
06782 { 06783 struct sip_request req; 06784 06785 req.method = sipmethod; 06786 if (init) { /* Seems like init always is 2 */ 06787 /* Bump branch even on initial requests */ 06788 p->branch ^= ast_random(); 06789 build_via(p); 06790 if (init > 1) 06791 initreqprep(&req, p, sipmethod); 06792 else 06793 reqprep(&req, p, sipmethod, 0, 1); 06794 } else 06795 reqprep(&req, p, sipmethod, 0, 1); 06796 06797 if (p->options && p->options->auth) 06798 add_header(&req, p->options->authheader, p->options->auth); 06799 append_date(&req); 06800 if (sipmethod == SIP_REFER) { /* Call transfer */ 06801 if (p->refer) { 06802 char buf[BUFSIZ]; 06803 if (!ast_strlen_zero(p->refer->refer_to)) 06804 add_header(&req, "Refer-To", p->refer->refer_to); 06805 if (!ast_strlen_zero(p->refer->referred_by)) { 06806 sprintf(buf, "%s <%s>", p->refer->referred_by_name, p->refer->referred_by); 06807 add_header(&req, "Referred-By", buf); 06808 } 06809 } 06810 } 06811 /* This new INVITE is part of an attended transfer. Make sure that the 06812 other end knows and replace the current call with this new call */ 06813 if (p->options && p->options->replaces && !ast_strlen_zero(p->options->replaces)) { 06814 add_header(&req, "Replaces", p->options->replaces); 06815 add_header(&req, "Require", "replaces"); 06816 } 06817 06818 add_header(&req, "Allow", ALLOWED_METHODS); 06819 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06820 if (p->options && p->options->addsipheaders && p->owner) { 06821 struct ast_channel *ast = p->owner; /* The owner channel */ 06822 struct varshead *headp = &ast->varshead; 06823 06824 if (!headp) 06825 ast_log(LOG_WARNING,"No Headp for the channel...ooops!\n"); 06826 else { 06827 const struct ast_var_t *current; 06828 AST_LIST_TRAVERSE(headp, current, entries) { 06829 /* SIPADDHEADER: Add SIP header to outgoing call */ 06830 if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) { 06831 char *content, *end; 06832 const char *header = ast_var_value(current); 06833 char *headdup = ast_strdupa(header); 06834 06835 /* Strip of the starting " (if it's there) */ 06836 if (*headdup == '"') 06837 headdup++; 06838 if ((content = strchr(headdup, ':'))) { 06839 *content++ = '\0'; 06840 content = ast_skip_blanks(content); /* Skip white space */ 06841 /* Strip the ending " (if it's there) */ 06842 end = content + strlen(content) -1; 06843 if (*end == '"') 06844 *end = '\0'; 06845 06846 add_header(&req, headdup, content); 06847 if (sipdebug) 06848 ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content); 06849 } 06850 } 06851 } 06852 } 06853 } 06854 if (sdp) { 06855 if (p->udptl && p->t38.state == T38_LOCAL_DIRECT) { 06856 ast_udptl_offered_from_local(p->udptl, 1); 06857 if (option_debug) 06858 ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); 06859 add_t38_sdp(&req, p); 06860 } else if (p->rtp) 06861 add_sdp(&req, p); 06862 } else { 06863 add_header_contentLength(&req, 0); 06864 } 06865 06866 if (!p->initreq.headers) 06867 initialize_initreq(p, &req); 06868 p->lastinvite = p->ocseq; 06869 return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq); 06870 }
| static int transmit_message_with_text | ( | struct sip_pvt * | p, | |
| const char * | text | |||
| ) | [static] |
Transmit text with SIP MESSAGE method.
Definition at line 7408 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().
07409 { 07410 struct sip_request req; 07411 07412 reqprep(&req, p, SIP_MESSAGE, 0, 1); 07413 add_text(&req, text); 07414 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07415 }
| 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 7048 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_inet_ntoa(), ast_log(), ast_test_flag, sip_pvt::expiry, sip_pvt::flags, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), LOG_WARNING, sip_pvt::ocseq, sip_pvt::ourip, S_OR, send_request(), SIP_NOTIFY, SIP_PAGE2_BUGGY_MWI, sip_pvt::subscribed, t, and XMIT_RELIABLE.
Referenced by sip_send_mwi_to_peer().
07049 { 07050 struct sip_request req; 07051 char tmp[500]; 07052 char *t = tmp; 07053 size_t maxbytes = sizeof(tmp); 07054 07055 initreqprep(&req, p, SIP_NOTIFY); 07056 add_header(&req, "Event", "message-summary"); 07057 add_header(&req, "Content-Type", default_notifymime); 07058 07059 ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no"); 07060 ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", 07061 S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip))); 07062 /* Cisco has a bug in the SIP stack where it can't accept the 07063 (0/0) notification. This can temporarily be disabled in 07064 sip.conf with the "buggymwi" option */ 07065 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)")); 07066 07067 if (p->subscribed) { 07068 if (p->expiry) 07069 add_header(&req, "Subscription-State", "active"); 07070 else /* Expired */ 07071 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 07072 } 07073 07074 if (t > tmp + sizeof(tmp)) 07075 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07076 07077 add_header_contentLength(&req, strlen(tmp)); 07078 add_line(&req, tmp); 07079 07080 if (!p->initreq.headers) 07081 initialize_initreq(p, &req); 07082 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07083 }
| 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 7094 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ALLOWED_METHODS, sip_request::headers, initialize_initreq(), sip_pvt::initreq, sip_pvt::ocseq, reqprep(), send_request(), SIP_NOTIFY, SUPPORTED_EXTENSIONS, and XMIT_RELIABLE.
Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().
07095 { 07096 struct sip_request req; 07097 char tmp[BUFSIZ/2]; 07098 07099 reqprep(&req, p, SIP_NOTIFY, 0, 1); 07100 snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq); 07101 add_header(&req, "Event", tmp); 07102 add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active"); 07103 add_header(&req, "Content-Type", "message/sipfrag;version=2.0"); 07104 add_header(&req, "Allow", ALLOWED_METHODS); 07105 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07106 07107 snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message); 07108 add_header_contentLength(&req, strlen(tmp)); 07109 add_line(&req, tmp); 07110 07111 if (!p->initreq.headers) 07112 initialize_initreq(p, &req); 07113 07114 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07115 }
| 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 7429 of file chan_sip.c.
References add_header(), ALLOWED_METHODS, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, DEFAULT_MAX_FORWARDS, sip_pvt::flags, get_header(), get_in_brackets(), sip_request::headers, sip_pvt::initreq, LOG_DEBUG, LOG_NOTICE, sip_pvt::ocseq, option_debug, sip_pvt::refer, REFER_SENT, sip_refer::refer_to, sip_refer::referred_by, reqprep(), send_request(), SIP_OUTGOING, SIP_REFER, sip_refer_allocate(), sipdebug, sip_refer::status, SUPPORTED_EXTENSIONS, sip_pvt::tag, and XMIT_RELIABLE.
Referenced by sip_transfer().
07430 { 07431 struct sip_request req = { 07432 .headers = 0, 07433 }; 07434 char from[256]; 07435 const char *of; 07436 char *c; 07437 char referto[256]; 07438 char *ttag, *ftag; 07439 char *theirtag = ast_strdupa(p->theirtag); 07440 07441 if (option_debug || sipdebug) 07442 ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest); 07443 07444 /* Are we transfering an inbound or outbound call ? */ 07445 if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 07446 of = get_header(&p->initreq, "To"); 07447 ttag = theirtag; 07448 ftag = p->tag; 07449 } else { 07450 of = get_header(&p->initreq, "From"); 07451 ftag = theirtag; 07452 ttag = p->tag; 07453 } 07454 07455 ast_copy_string(from, of, sizeof(from)); 07456 of = get_in_brackets(from); 07457 ast_string_field_set(p, from, of); 07458 if (strncmp(of, "sip:", 4)) 07459 ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 07460 else 07461 of += 4; 07462 /* Get just the username part */ 07463 if ((c = strchr(dest, '@'))) 07464 c = NULL; 07465 else if ((c = strchr(of, '@'))) 07466 *c++ = '\0'; 07467 if (c) 07468 snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c); 07469 else 07470 snprintf(referto, sizeof(referto), "<sip:%s>", dest); 07471 07472 /* save in case we get 407 challenge */ 07473 sip_refer_allocate(p); 07474 ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to)); 07475 ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by)); 07476 p->refer->status = REFER_SENT; /* Set refer status */ 07477 07478 reqprep(&req, p, SIP_REFER, 0, 1); 07479 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07480 07481 add_header(&req, "Refer-To", referto); 07482 add_header(&req, "Allow", ALLOWED_METHODS); 07483 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 07484 if (!ast_strlen_zero(p->our_contact)) 07485 add_header(&req, "Referred-By", p->our_contact); 07486 07487 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07488 /* We should propably wait for a NOTIFY here until we ack the transfer */ 07489 /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */ 07490 07491 /*! \todo In theory, we should hang around and wait for a reply, before 07492 returning to the dial plan here. Don't know really how that would 07493 affect the transfer() app or the pbx, but, well, to make this 07494 useful we should have a STATUS code on transfer(). 07495 */ 07496 }
| 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 7217 of file chan_sip.c.
References __ourip, add_header(), add_header_contentLength(), append_history, ast_log(), ast_random(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_free, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose(), ASTOBJ_REF, bindaddr, sip_pvt::branch, build_callid_registry(), build_contact(), build_reply_digest(), build_via(), sip_registry::call, sip_registry::callid_valid, create_addr(), DEFAULT_MAX_FORWARDS, exten, sip_pvt::flags, sip_request::headers, init_req(), initialize_initreq(), sip_pvt::initreq, sip_request::lines, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, make_our_tag(), sip_pvt::noncecount, sip_registry::noncecount, sip_pvt::ocseq, sip_registry::ocseq, option_debug, sip_registry::portno, REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, sip_registry::regstate, sched, send_request(), sip_alloc(), sip_debug_test_pvt(), sip_destroy(), sip_methods, SIP_NO_HISTORY, SIP_OUTGOING, sip_reg_timeout(), SIP_REGISTER, sipdebug, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_registry::timeout, TRUE, username, and XMIT_CRITICAL.
Referenced by __sip_do_register(), do_register_auth(), and sip_reg_timeout().
07218 { 07219 struct sip_request req; 07220 char from[256]; 07221 char to[256]; 07222 char tmp[80]; 07223 char addr[80]; 07224 struct sip_pvt *p; 07225 07226 /* exit if we are already in process with this registrar ?*/ 07227 if ( r == NULL || ((auth==NULL) && (r->regstate==REG_STATE_REGSENT || r->regstate==REG_STATE_AUTHSENT))) { 07228 ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname); 07229 return 0; 07230 } 07231 07232 if (r->call) { /* We have a registration */ 07233 if (!auth) { 07234 ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname); 07235 return 0; 07236 } else { 07237 p = r->call; 07238 make_our_tag(p->tag, sizeof(p->tag)); /* create a new local tag for every register attempt */ 07239 ast_string_field_free(p, theirtag); /* forget their old tag, so we don't match tags when getting response */ 07240 } 07241 } else { 07242 /* Build callid for registration if we haven't registered before */ 07243 if (!r->callid_valid) { 07244 build_callid_registry(r, __ourip, default_fromdomain); 07245 r->callid_valid = TRUE; 07246 } 07247 /* Allocate SIP packet for registration */ 07248 if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER))) { 07249 ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n"); 07250 return 0; 07251 } 07252 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 07253 append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname); 07254 /* Find address to hostname */ 07255 if (create_addr(p, r->hostname)) { 07256 /* we have what we hope is a temporary network error, 07257 * probably DNS. We need to reschedule a registration try */ 07258 sip_destroy(p); 07259 if (r->timeout > -1) { 07260 ast_sched_del(sched, r->timeout); 07261 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 07262 ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout); 07263 } else { 07264 r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r); 07265 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); 07266 } 07267 r->regattempts++; 07268 return 0; 07269 } 07270 /* Copy back Call-ID in case create_addr changed it */ 07271 ast_string_field_set(r, callid, p->callid); 07272 if (r->portno) 07273 p->sa.sin_port = htons(r->portno); 07274 else /* Set registry port to the port set from the peer definition/srv or default */ 07275 r->portno = ntohs(p->sa.sin_port); 07276 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */ 07277 r->call=p; /* Save pointer to SIP packet */ 07278 p->registry = ASTOBJ_REF(r); /* Add pointer to registry in packet */ 07279 if (!ast_strlen_zero(r->secret)) /* Secret (password) */ 07280 ast_string_field_set(p, peersecret, r->secret); 07281 if (!ast_strlen_zero(r->md5secret)) 07282 ast_string_field_set(p, peermd5secret, r->md5secret); 07283 /* User name in this realm 07284 - if authuser is set, use that, otherwise use username */ 07285 if (!ast_strlen_zero(r->authuser)) { 07286 ast_string_field_set(p, peername, r->authuser); 07287 ast_string_field_set(p, authname, r->authuser); 07288 } else if (!ast_strlen_zero(r->username)) { 07289 ast_string_field_set(p, peername, r->username); 07290 ast_string_field_set(p, authname, r->username); 07291 ast_string_field_set(p, fromuser, r->username); 07292 } 07293 if (!ast_strlen_zero(r->username)) 07294 ast_string_field_set(p, username, r->username); 07295 /* Save extension in packet */ 07296 ast_string_field_set(p, exten, r->contact); 07297 07298 /* 07299 check which address we should use in our contact header 07300 based on whether the remote host is on the external or 07301 internal network so we can register through nat 07302 */ 07303 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 07304 p->ourip = bindaddr.sin_addr; 07305 build_contact(p); 07306 } 07307 07308 /* set up a timeout */ 07309 if (auth == NULL) { 07310 if (r->timeout > -1) { 07311 ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout); 07312 ast_sched_del(sched, r->timeout); 07313 } 07314 r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r); 07315 if (option_debug) 07316 ast_log(LOG_DEBUG, "Scheduled a registration timeout for %s id #%d \n", r->hostname, r->timeout); 07317 } 07318 07319 if (strchr(r->username, '@')) { 07320 snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag); 07321 if (!ast_strlen_zero(p->theirtag)) 07322 snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag); 07323 else 07324 snprintf(to, sizeof(to), "<sip:%s>", r->username); 07325 } else { 07326 snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag); 07327 if (!ast_strlen_zero(p->theirtag)) 07328 snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag); 07329 else 07330 snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost); 07331 } 07332 07333 /* Fromdomain is what we are registering to, regardless of actual 07334 host name from SRV */ 07335 if (!ast_strlen_zero(p->fromdomain)) { 07336 if (r->portno && r->portno != STANDARD_SIP_PORT) 07337 snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno); 07338 else 07339 snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain); 07340 } else { 07341 if (r->portno && r->portno != STANDARD_SIP_PORT) 07342 snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno); 07343 else 07344 snprintf(addr, sizeof(addr), "sip:%s", r->hostname); 07345 } 07346 ast_string_field_set(p, uri, addr); 07347 07348 p->branch ^= ast_random(); 07349 07350 init_req(&req, sipmethod, addr); 07351 07352 /* Add to CSEQ */ 07353 snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text); 07354 p->ocseq = r->ocseq; 07355 07356 build_via(p); 07357 add_header(&req, "Via", p->via); 07358 add_header(&req, "From", from); 07359 add_header(&req, "To", to); 07360 add_header(&req, "Call-ID", p->callid); 07361 add_header(&req, "CSeq", tmp); 07362 if (!ast_strlen_zero(global_useragent)) 07363 add_header(&req, "User-Agent", global_useragent); 07364 add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS); 07365 07366 07367 if (auth) /* Add auth header */ 07368 add_header(&req, authheader, auth); 07369 else if (!ast_strlen_zero(r->nonce)) { 07370 char digest[1024]; 07371 07372 /* We have auth data to reuse, build a digest header! */ 07373 if (sipdebug) 07374 ast_log(LOG_DEBUG, " >>> Re-using Auth data for %s@%s\n", r->username, r->hostname); 07375 ast_string_field_set(p, realm, r->realm); 07376 ast_string_field_set(p, nonce, r->nonce); 07377 ast_string_field_set(p, domain, r->domain); 07378 ast_string_field_set(p, opaque, r->opaque); 07379 ast_string_field_set(p, qop, r->qop); 07380 r->noncecount++; 07381 p->noncecount = r->noncecount; 07382 07383 memset(digest,0,sizeof(digest)); 07384 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) 07385 add_header(&req, "Authorization", digest); 07386 else 07387 ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname); 07388 07389 } 07390 07391 snprintf(tmp, sizeof(tmp), "%d", default_expiry); 07392 add_header(&req, "Expires", tmp); 07393 add_header(&req, "Contact", p->our_contact); 07394 add_header(&req, "Event", "registration"); 07395 add_header_contentLength(&req, 0); 07396 07397 initialize_initreq(p, &req); 07398 if (sip_debug_test_pvt(p)) 07399 ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines); 07400 r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT; 07401 r->regattempts++; /* Another attempt */ 07402 if (option_debug > 3) 07403 ast_verbose("REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname); 07404 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 07405 }
| static int transmit_reinvite_with_sdp | ( | struct sip_pvt * | p | ) | [static] |
Transmit reinvite with SDP.
Definition at line 6501 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().
06502 { 06503 struct sip_request req; 06504 06505 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06506 06507 add_header(&req, "Allow", ALLOWED_METHODS); 06508 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06509 if (sipdebug) 06510 add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)"); 06511 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) 06512 append_history(p, "ReInv", "Re-invite sent"); 06513 add_sdp(&req, p); 06514 /* Use this as the basis */ 06515 initialize_initreq(p, &req); 06516 p->lastinvite = p->ocseq; 06517 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06518 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06519 }
| 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 6525 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().
06526 { 06527 struct sip_request req; 06528 06529 reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1); 06530 06531 add_header(&req, "Allow", ALLOWED_METHODS); 06532 add_header(&req, "Supported", SUPPORTED_EXTENSIONS); 06533 if (sipdebug) 06534 add_header(&req, "X-asterisk-info", "SIP re-invite (T38 switchover)"); 06535 ast_udptl_offered_from_local(p->udptl, 1); 06536 add_t38_sdp(&req, p); 06537 /* Use this as the basis */ 06538 initialize_initreq(p, &req); 06539 ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Change direction of this dialog */ 06540 p->lastinvite = p->ocseq; 06541 return send_request(p, &req, XMIT_CRITICAL, p->ocseq); 06542 }
| static int transmit_request | ( | struct sip_pvt * | p, | |
| int | sipmethod, | |||
| int | inc, | |||
| enum xmittype | reliable, | |||
| int | newbranch | |||
| ) | [static] |
Transmit generic SIP request.
Definition at line 7520 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().
07521 { 07522 struct sip_request resp; 07523 07524 if (sipmethod == SIP_ACK) 07525 p->invitestate = INV_CONFIRMED; 07526 07527 reqprep(&resp, p, sipmethod, seqno, newbranch); 07528 add_header_contentLength(&resp, 0); 07529 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07530 }
| 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 7533 of file chan_sip.c.
References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), ast_strlen_zero(), sip_invite_param::auth_type, build_reply_digest(), ast_channel::hangupcause, LOG_WARNING, sip_pvt::ocseq, sip_pvt::options, sip_pvt::owner, PROXY_AUTH, reqprep(), send_request(), SIP_BYE, and WWW_AUTH.
Referenced by __sip_autodestruct(), check_pendings(), and sip_hangup().
07534 { 07535 struct sip_request resp; 07536 07537 reqprep(&resp, p, sipmethod, seqno, newbranch); 07538 if (!ast_strlen_zero(p->realm)) { 07539 char digest[1024]; 07540 07541 memset(digest, 0, sizeof(digest)); 07542 if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) { 07543 if (p->options && p->options->auth_type == PROXY_AUTH) 07544 add_header(&resp, "Proxy-Authorization", digest); 07545 else if (p->options && p->options->auth_type == WWW_AUTH) 07546 add_header(&resp, "Authorization", digest); 07547 else /* Default, to be backwards compatible (maybe being too careful, but leaving it for now) */ 07548 add_header(&resp, "Proxy-Authorization", digest); 07549 } else 07550 ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid); 07551 } 07552 /* If we are hanging up and know a cause for that, send it in clear text to make 07553 debugging easier. */ 07554 if (sipmethod == SIP_BYE && p->owner && p->owner->hangupcause) { 07555 char buf[10]; 07556 07557 add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause)); 07558 snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause); 07559 add_header(&resp, "X-Asterisk-HangupCauseCode", buf); 07560 } 07561 07562 add_header_contentLength(&resp, 0); 07563 return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq); 07564 }
| static int transmit_response | ( | struct sip_pvt * | p, | |
| const char * | msg, | |||
| const struct sip_request * | req | |||
| ) | [static] |
Transmit response, no retransmits.
Definition at line 5820 of file chan_sip.c.
References __transmit_response(), and XMIT_UNRELIABLE.
05821 { 05822 return __transmit_response(p, msg, req, XMIT_UNRELIABLE); 05823 }
| 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 5839 of file chan_sip.c.
References __transmit_response(), and XMIT_CRITICAL.
Referenced by handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_subscribe(), sip_hangup(), and sip_sipredirect().
05840 { 05841 return __transmit_response(p, msg, req, XMIT_CRITICAL); 05842 }
| 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 5770 of file chan_sip.c.
References __ourip, __transmit_response(), ast_copy_flags, ast_log(), ast_random(), ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_free_all, ast_string_field_init, ast_string_field_set, ast_test_flag, build_via(), do_setnat(), global_flags, INITIAL_CSEQ, LOG_NOTICE, make_our_tag(), SIP_NAT, SIP_NAT_ROUTE, SIP_NO_HISTORY, and XMIT_UNRELIABLE.
05771 { 05772 struct sip_pvt *p = NULL; 05773 05774 if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) { 05775 ast_log(LOG_NOTICE, "Failed to get temporary pvt\n"); 05776 return -1; 05777 } 05778 05779 /* if the structure was just allocated, initialize it */ 05780 if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) { 05781 ast_set_flag(&p->flags[0], SIP_NO_HISTORY); 05782 if (ast_string_field_init(p, 512)) 05783 return -1; 05784 } 05785 05786 /* Initialize the bare minimum */ 05787 p->method = intended_method; 05788 05789 if (sin) { 05790 p->sa = *sin; 05791 if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip)) 05792 p->ourip = __ourip; 05793 } else 05794 p->ourip = __ourip; 05795 05796 p->branch = ast_random(); 05797 make_our_tag(p->tag, sizeof(p->tag)); 05798 p->ocseq = INITIAL_CSEQ; 05799 05800 if (useglobal_nat && sin) { 05801 ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT); 05802 p->recv = *sin; 05803 do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE); 05804 } 05805 05806 ast_string_field_set(p, fromdomain, default_fromdomain); 05807 build_via(p); 05808 ast_string_field_set(p, callid, callid); 05809 05810 /* Use this temporary pvt structure to send the message */ 05811 __transmit_response(p, msg, req, XMIT_UNRELIABLE); 05812 05813 /* Free the string fields, but not the pool space */ 05814 ast_string_field_free_all(p); 05815 05816 return 0; 05817 }
| 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 5867 of file chan_sip.c.
References add_header(), add_header_contentLength(), respprep(), and send_response().
Referenced by handle_request(), and handle_request_options().
05868 { 05869 struct sip_request resp; 05870 respprep(&resp, p, msg, req); 05871 add_header(&resp, "Accept", "application/sdp"); 05872 add_header_contentLength(&resp, 0); 05873 return send_response(p, &resp, reliable, 0); 05874 }
| 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 5877 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_history, ast_log(), get_header(), LOG_WARNING, sip_pvt::noncecount, respprep(), and send_response().
Referenced by check_auth(), and transmit_fake_auth_response().
05878 { 05879 struct sip_request resp; 05880 char tmp[512]; 05881 int seqno = 0; 05882 05883 if (reliable && (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1)) { 05884 ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq")); 05885 return -1; 05886 } 05887 /* Stale means that they sent us correct authentication, but 05888 based it on an old challenge (nonce) */ 05889 snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : ""); 05890 respprep(&resp, p, msg, req); 05891 add_header(&resp, header, tmp); 05892 add_header_contentLength(&resp, 0); 05893 append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount); 05894 return send_response(p, &resp, reliable, seqno); 05895 }
| 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 5857 of file chan_sip.c.
References add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by register_verify().
05858 { 05859 struct sip_request resp; 05860 respprep(&resp, p, msg, req); 05861 append_date(&resp); 05862 add_header_contentLength(&resp, 0); 05863 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 05864 }
| 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 6430 of file chan_sip.c.
References add_sdp(), ast_log(), ast_rtp_codec_setpref(), ast_test_flag, sip_pvt::autoframing, sip_pvt::flags, get_header(), LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, sip_pvt::pendinginvite, sip_pvt::prefs, respprep(), sip_pvt::rtp, send_response(), SIP_OUTGOING, and try_suggested_sip_codec().
Referenced by handle_invite_replaces(), handle_request_invite(), sip_answer(), sip_indicate(), and sip_write().
06431 { 06432 struct sip_request resp; 06433 int seqno; 06434 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06435 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06436 return -1; 06437 } 06438 respprep(&resp, p, msg, req); 06439 if (p->rtp) { 06440 if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { 06441 if (option_debug) 06442 ast_log(LOG_DEBUG, "Setting framing from config on incoming call\n"); 06443 ast_rtp_codec_setpref(p->rtp, &p->prefs); 06444 } 06445 try_suggested_sip_codec(p); 06446 add_sdp(&resp, p); 06447 } else 06448 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid); 06449 if (reliable && !p->pendinginvite) 06450 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06451 return send_response(p, &resp, reliable, seqno); 06452 }
| 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 6392 of file chan_sip.c.
References add_t38_sdp(), ast_log(), ast_udptl_offered_from_local(), get_header(), LOG_ERROR, LOG_WARNING, sip_pvt::pendinginvite, respprep(), send_response(), and sip_pvt::udptl.
Referenced by handle_request_invite(), sip_answer(), and sip_handle_t38_reinvite().
06393 { 06394 struct sip_request resp; 06395 int seqno; 06396 06397 if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) { 06398 ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq")); 06399 return -1; 06400 } 06401 respprep(&resp, p, msg, req); 06402 if (p->udptl) { 06403 ast_udptl_offered_from_local(p->udptl, 0); 06404 add_t38_sdp(&resp, p); 06405 } else 06406 ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid); 06407 if (retrans && !p->pendinginvite) 06408 p->pendinginvite = seqno; /* Buggy clients sends ACK on RINGING too */ 06409 return send_response(p, &resp, retrans, seqno); 06410 }
| 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 5826 of file chan_sip.c.
References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.
Referenced by handle_request_invite().
05827 { 05828 struct sip_request resp; 05829 respprep(&resp, p, msg, req); 05830 append_date(&resp); 05831 add_header(&resp, "Unsupported", unsupported); 05832 add_header_contentLength(&resp, 0); 05833 return send_response(p, &resp, XMIT_UNRELIABLE, 0); 05834 }
| 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 7086 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().
07087 { 07088 if (!p->initreq.headers) /* Initialize first request before sending */ 07089 initialize_initreq(p, req); 07090 return send_request(p, req, XMIT_UNRELIABLE, p->ocseq); 07091 }
| 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 6873 of file chan_sip.c.
References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), ast_log(), AST_MAX_EXTENSION, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, sip_pvt::expiry, find_subscription_type(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, NONE, sip_pvt::ocseq, PIDF_XML, reqprep(), send_request(), SIP_NOTIFY, strsep(), sip_pvt::subscribed, t, XMIT_RELIABLE, and XPIDF_XML.
Referenced by __sip_autodestruct(), cb_extensionstate(), and handle_request_subscribe().
06874 { 06875 char tmp[4000], from[256], to[256]; 06876 char *t = tmp, *c, *mfrom, *mto; 06877 size_t maxbytes = sizeof(tmp); 06878 struct sip_request req; 06879 char hint[AST_MAX_EXTENSION]; 06880 char *statestring = "terminated"; 06881 const struct cfsubscription_types *subscriptiontype; 06882 enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN; 06883 char *pidfstate = "--"; 06884 char *pidfnote= "Ready"; 06885 06886 memset(from, 0, sizeof(from)); 06887 memset(to, 0, sizeof(to)); 06888 memset(tmp, 0, sizeof(tmp)); 06889 06890 switch (state) { 06891 case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE): 06892 statestring = (global_notifyringing) ? "early" : "confirmed"; 06893 local_state = NOTIFY_INUSE; 06894 pidfstate = "busy"; 06895 pidfnote = "Ringing"; 06896 break; 06897 case AST_EXTENSION_RINGING: 06898 statestring = "early"; 06899 local_state = NOTIFY_INUSE; 06900 pidfstate = "busy"; 06901 pidfnote = "Ringing"; 06902 break; 06903 case AST_EXTENSION_INUSE: 06904 statestring = "confirmed"; 06905 local_state = NOTIFY_INUSE; 06906 pidfstate = "busy"; 06907 pidfnote = "On the phone"; 06908 break; 06909 case AST_EXTENSION_BUSY: 06910 statestring = "confirmed"; 06911 local_state = NOTIFY_CLOSED; 06912 pidfstate = "busy"; 06913 pidfnote = "On the phone"; 06914 break; 06915 case AST_EXTENSION_UNAVAILABLE: 06916 statestring = "terminated"; 06917 local_state = NOTIFY_CLOSED; 06918 pidfstate = "away"; 06919 pidfnote = "Unavailable"; 06920 break; 06921 case AST_EXTENSION_ONHOLD: 06922 statestring = "confirmed"; 06923 local_state = NOTIFY_INUSE; 06924 pidfstate = "busy"; 06925 pidfnote = "On Hold"; 06926 break; 06927 case AST_EXTENSION_NOT_INUSE: 06928 default: 06929 /* Default setting */ 06930 break; 06931 } 06932 06933 subscriptiontype = find_subscription_type(p->subscribed); 06934 06935 /* Check which device/devices we are watching and if they are registered */ 06936 if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) { 06937 /* If they are not registered, we will override notification and show no availability */ 06938 if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) { 06939 local_state = NOTIFY_CLOSED; 06940 pidfstate = "away"; 06941 pidfnote = "Not online"; 06942 } 06943 } 06944 06945 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 06946 c = get_in_brackets(from); 06947 if (strncmp(c, "sip:", 4)) { 06948 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 06949 return -1; 06950 } 06951 mfrom = strsep(&c, ";"); /* trim ; and beyond */ 06952 06953 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 06954 c = get_in_brackets(to); 06955 if (strncmp(c, "sip:", 4)) { 06956 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 06957 return -1; 06958 } 06959 mto = strsep(&c, ";"); /* trim ; and beyond */ 06960 06961 reqprep(&req, p, SIP_NOTIFY, 0, 1); 06962 06963 06964 add_header(&req, "Event", subscriptiontype->event); 06965 add_header(&req, "Content-Type", subscriptiontype->mediatype); 06966 switch(state) { 06967 case AST_EXTENSION_DEACTIVATED: 06968 if (timeout) 06969 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 06970 else { 06971 add_header(&req, "Subscription-State", "terminated;reason=probation"); 06972 add_header(&req, "Retry-After", "60"); 06973 } 06974 break; 06975 case AST_EXTENSION_REMOVED: 06976 add_header(&req, "Subscription-State", "terminated;reason=noresource"); 06977 break; 06978 default: 06979 if (p->expiry) 06980 add_header(&req, "Subscription-State", "active"); 06981 else /* Expired */ 06982 add_header(&req, "Subscription-State", "terminated;reason=timeout"); 06983 } 06984 switch (p->subscribed) { 06985 case XPIDF_XML: 06986 case CPIM_PIDF_XML: 06987 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 06988 ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"); 06989 ast_build_string(&t, &maxbytes, "<presence>\n"); 06990 ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom); 06991 ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten); 06992 ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto); 06993 ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed"); 06994 ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline"); 06995 ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n"); 06996 break; 06997 case PIDF_XML: /* Eyebeam supports this format */ 06998 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); 06999 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); 07000 ast_build_string(&t, &maxbytes, "<pp:person><status>\n"); 07001 if (pidfstate[0] != '-') 07002 ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate); 07003 ast_build_string(&t, &maxbytes, "</status></pp:person>\n"); 07004 ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */ 07005 ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */ 07006 ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto); 07007 if (pidfstate[0] == 'b') /* Busy? Still open ... */ 07008 ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n"); 07009 else 07010 ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed"); 07011 ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n"); 07012 break; 07013 case DIALOG_INFO_XML: /* SNOM subscribes in this format */ 07014 ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n"); 07015 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); 07016 if ((state & AST_EXTENSION_RINGING) && global_notifyringing) 07017 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten); 07018 else 07019 ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten); 07020 ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring); 07021 if (state == AST_EXTENSION_ONHOLD) { 07022 ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n" 07023 "<param pname=\"+sip.rendering\" pvalue=\"no\">\n" 07024 "</target>\n</local>\n", mto); 07025 } 07026 ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n"); 07027 break; 07028 case NONE: 07029 default: 07030 break; 07031 } 07032 07033 if (t > tmp + sizeof(tmp)) 07034 ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n"); 07035 07036 add_header_contentLength(&req, strlen(tmp)); 07037 add_line(&req, tmp); 07038 07039 return send_request(p, &req, XMIT_RELIABLE, p->ocseq); 07040 }
| static void try_suggested_sip_codec | ( | struct sip_pvt * | p | ) | [static] |
Try setting codec suggested by the SIP_CODEC channel variable.
Definition at line 3429 of file chan_sip.c.
References ast_getformatbyname(), ast_log(), sip_pvt::capability, fmt, sip_pvt::jointcapability, LOG_NOTICE, sip_pvt::owner, and pbx_builtin_getvar_helper().
Referenced by sip_answer(), and transmit_response_with_sdp().
03430 { 03431 int fmt; 03432 const char *codec; 03433 03434 codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC"); 03435 if (!codec) 03436 return; 03437 03438 fmt = ast_getformatbyname(codec); 03439 if (fmt) { 03440 ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec); 03441 if (p->jointcapability & fmt) { 03442 p->jointcapability &= fmt; 03443 p->capability &= fmt; 03444 } else 03445 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n"); 03446 } else 03447 ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec); 03448 return; 03449 }
| static int unload_module | ( | void | ) | [static] |
PBX unload module API.
Definition at line 17465 of file chan_sip.c.
References __sip_destroy(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_free_ha(), ast_manager_unregister(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_udptl_proto_unregister(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, checksipdomain_function, clear_realm_authentication(), clear_sip_domains(), cli_sip, iflist, localaddr, sip_pvt::next, sip_pvt::owner, peerl, regl, sched, sched_context_destroy(), sip_destroy_peer(), sip_destroy_user(), sip_header_function, sip_registry_destroy(), sip_rtp, sip_tech, sip_udptl, sipchaninfo_function, sippeer_function, sipsock, TRUE, and userl.
17466 { 17467 struct sip_pvt *p, *pl; 17468 17469 /* First, take us out of the channel type list */ 17470 ast_channel_unregister(&sip_tech); 17471 17472 /* Unregister dial plan functions */ 17473 ast_custom_function_unregister(&sipchaninfo_function); 17474 ast_custom_function_unregister(&sippeer_function); 17475 ast_custom_function_unregister(&sip_header_function); 17476 ast_custom_function_unregister(&checksipdomain_function); 17477 17478 /* Unregister dial plan applications */ 17479 ast_unregister_application(app_dtmfmode); 17480 ast_unregister_application(app_sipaddheader); 17481 17482 /* Unregister CLI commands */ 17483 ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry)); 17484 17485 /* Disconnect from the RTP subsystem */ 17486 ast_rtp_proto_unregister(&sip_rtp); 17487 17488 /* Disconnect from UDPTL */ 17489 ast_udptl_proto_unregister(&sip_udptl); 17490 17491 /* Unregister AMI actions */ 17492 ast_manager_unregister("SIPpeers"); 17493 ast_manager_unregister("SIPshowpeer"); 17494 17495 ast_mutex_lock(&iflock); 17496 /* Hangup all interfaces if they have an owner */ 17497 for (p = iflist; p ; p = p->next) { 17498 if (p->owner) 17499 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 17500 } 17501 ast_mutex_unlock(&iflock); 17502 17503 ast_mutex_lock(&monlock); 17504 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) { 17505 pthread_cancel(monitor_thread); 17506 pthread_kill(monitor_thread, SIGURG); 17507 pthread_join(monitor_thread, NULL); 17508 } 17509 monitor_thread = AST_PTHREADT_STOP; 17510 ast_mutex_unlock(&monlock); 17511 17512 ast_mutex_lock(&iflock); 17513 /* Destroy all the interfaces and free their memory */ 17514 p = iflist; 17515 while (p) { 17516 pl = p; 17517 p = p->next; 17518 __sip_destroy(pl, TRUE); 17519 } 17520 iflist = NULL; 17521 ast_mutex_unlock(&iflock); 17522 17523 /* Free memory for local network address mask */ 17524 ast_free_ha(localaddr); 17525 17526 ASTOBJ_CONTAINER_DESTROYALL(&userl, sip_destroy_user); 17527 ASTOBJ_CONTAINER_DESTROY(&userl); 17528 ASTOBJ_CONTAINER_DESTROYALL(&peerl, sip_destroy_peer); 17529 ASTOBJ_CONTAINER_DESTROY(&peerl); 17530 ASTOBJ_CONTAINER_DESTROYALL(®l, sip_registry_destroy); 17531 ASTOBJ_CONTAINER_DESTROY(®l); 17532 17533 clear_realm_authentication(authl); 17534 clear_sip_domains(); 17535 close(sipsock); 17536 sched_context_destroy(sched); 17537 17538 return 0; 17539 }
| 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 2995 of file chan_sip.c.
References ast_clear_flag, ast_device_state_changed(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_test_flag, ASTOBJ_UNREF, sip_peer::call_limit, sip_user::call_limit, DEC_CALL_LIMIT, DEC_CALL_RINGING, FALSE, find_peer(), find_user(), sip_pvt::flags, INC_CALL_LIMIT, INC_CALL_RINGING, sip_peer::inRinging, sip_peer::inUse, sip_user::inUse, inuse, LOG_DEBUG, LOG_ERROR, LOG_WARNING, name, option_debug, SIP_CALL_LIMIT, sip_destroy_peer(), sip_destroy_user(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_INC_RINGING, SIP_PAGE2_OUTGOING_CALL, sip_peer_hold(), and sipdebug.
Referenced by __sip_destroy(), handle_request_invite(), handle_response_invite(), sip_call(), and sip_hangup().
02996 { 02997 char name[256]; 02998 int *inuse = NULL, *call_limit = NULL, *inringing = NULL; 02999 int outgoing = ast_test_flag(&fup->flags[1], SIP_PAGE2_OUTGOING_CALL); 03000 struct sip_user *u = NULL; 03001 struct sip_peer *p = NULL; 03002 03003 if (option_debug > 2) 03004 ast_log(LOG_DEBUG, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming"); 03005 /* Test if we need to check call limits, in order to avoid 03006 realtime lookups if we do not need it */ 03007 if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT)) 03008 return 0; 03009 03010 ast_copy_string(name, fup->username, sizeof(name)); 03011 03012 /* Check the list of users only for incoming calls */ 03013 if (global_limitonpeers == FALSE && !outgoing && (u = find_user(name, 1))) { 03014 inuse = &u->inUse; 03015 call_limit = &u->call_limit; 03016 inringing = NULL; 03017 } else if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, 1) ) ) { /* Try to find peer */ 03018 inuse = &p->inUse; 03019 call_limit = &p->call_limit; 03020 inringing = &p->inRinging; 03021 ast_copy_string(name, fup->peername, sizeof(name)); 03022 } 03023 if (!p && !u) { 03024 if (option_debug > 1) 03025 ast_log(LOG_DEBUG, "%s is not a local device, no call limit\n", name); 03026 return 0; 03027 } 03028 03029 switch(event) { 03030 /* incoming and outgoing affects the inUse counter */ 03031 case DEC_CALL_LIMIT: 03032 if ( *inuse > 0 ) { 03033 if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) { 03034 (*inuse)--; 03035 ast_clear_flag(&fup->flags[0], SIP_INC_COUNT); 03036 } 03037 } else { 03038 *inuse = 0; 03039 } 03040 if (inringing) { 03041 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03042 if (*inringing > 0) 03043 (*inringing)--; 03044 else 03045 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", fup->peername); 03046 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03047 } 03048 } 03049 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) 03050 sip_peer_hold(fup, 0); 03051 if (option_debug > 1 || sipdebug) { 03052 ast_log(LOG_DEBUG, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *call_limit); 03053 } 03054 break; 03055 03056 case INC_CALL_RINGING: 03057 case INC_CALL_LIMIT: 03058 if (*call_limit > 0 ) { 03059 if (*inuse >= *call_limit) { 03060 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); 03061 if (u) 03062 ASTOBJ_UNREF(u, sip_destroy_user); 03063 else 03064 ASTOBJ_UNREF(p, sip_destroy_peer); 03065 return -1; 03066 } 03067 } 03068 if (inringing && (event == INC_CALL_RINGING)) { 03069 if (!ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03070 (*inringing)++; 03071 ast_set_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03072 } 03073 } 03074 /* Continue */ 03075 (*inuse)++; 03076 ast_set_flag(&fup->flags[0], SIP_INC_COUNT); 03077 if (option_debug > 1 || sipdebug) { 03078 ast_log(LOG_DEBUG, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", u ? "user":"peer", name, *inuse, *call_limit); 03079 } 03080 break; 03081 03082 case DEC_CALL_RINGING: 03083 if (inringing) { 03084 if (ast_test_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING)) { 03085 if (*inringing > 0) 03086 (*inringing)--; 03087 else 03088 ast_log(LOG_WARNING, "Inringing for peer '%s' < 0?\n", p->name); 03089 ast_clear_flag(&fup->flags[1], SIP_PAGE2_INC_RINGING); 03090 } 03091 } 03092 break; 03093 03094 default: 03095 ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event); 03096 } 03097 if (p) { 03098 ast_device_state_changed("SIP/%s", p->name); 03099 ASTOBJ_UNREF(p, sip_destroy_peer); 03100 } else /* u must be set */ 03101 ASTOBJ_UNREF(u, sip_destroy_user); 03102 return 0; 03103 }
| static void update_peer | ( | struct sip_peer * | p, | |
| int | expiry | |||
| ) | [static] |
Update peer data in database (if used).
Definition at line 2392 of file chan_sip.c.
References sip_peer::addr, ast_test_flag, sip_peer::flags, sip_peer::fullcontact, global_flags, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, SIP_REALTIME, and sip_peer::username.
Referenced by register_verify().
02393 { 02394 int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS); 02395 if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE) && 02396 (ast_test_flag(&p->flags[0], SIP_REALTIME) || rtcachefriends)) { 02397 realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry); 02398 } 02399 }
struct in_addr __ourip [static] |
Definition at line 1188 of file chan_sip.c.
int allow_external_domains [static] |
Accept calls to external SIP domains?
Definition at line 554 of file chan_sip.c.
int apeerobjs = 0 [static] |
Autocreated peer objects
Definition at line 570 of file chan_sip.c.
char* app_dtmfmode = "SIPDtmfMode" [static] |
Definition at line 17005 of file chan_sip.c.
char* app_sipaddheader = "SIPAddHeader" [static] |
Definition at line 17007 of file chan_sip.c.
Definition at line 1177 of file chan_sip.c.
Referenced by build_reply_digest(), sip_do_reload(), sip_show_settings(), and unload_module().
int autocreatepeer [static] |
Auto creation of peers at registration? Default off.
Definition at line 534 of file chan_sip.c.
struct sockaddr_in bindaddr = { 0, } [static] |
The address we bind to
Definition at line 1182 of file chan_sip.c.
struct ast_custom_function checksipdomain_function [static] |
struct ast_cli_entry cli_sip[] [static] |
struct ast_cli_entry cli_sip_debug_deprecated [static] |
Initial value:
{ { "sip", "debug", NULL },
sip_do_debug_deprecated, "Enable SIP debugging",
debug_usage }
Definition at line 17291 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 17296 of file chan_sip.c.
int compactheaders [static] |
send compact sip headers
Definition at line 548 of file chan_sip.c.
const char config[] = "sip.conf" [static] |
Definition at line 222 of file chan_sip.c.
char debug_usage[] [static] |
Definition at line 11311 of file chan_sip.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1191 of file chan_sip.c.
Referenced by sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), and sip_do_debug_peer().
char default_callerid[AST_MAX_EXTENSION] [static] |
Definition at line 514 of file chan_sip.c.
char default_context[AST_MAX_CONTEXT] [static] |
Definition at line 511 of file chan_sip.c.
int default_expiry = DEFAULT_DEFAULT_EXPIRY [static] |
Definition at line 185 of file chan_sip.c.
char default_fromdomain[AST_MAX_EXTENSION] [static] |
Definition at line 515 of file chan_sip.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled.
Definition at line 213 of file chan_sip.c.
char default_language[MAX_LANGUAGE] [static] |
Definition at line 513 of file chan_sip.c.
int default_maxcallbitrate [static] |
Maximum bitrate for call
Definition at line 522 of file chan_sip.c.
char default_mohinterpret[MAX_MUSICCLASS] [static] |
Global setting for moh class to use when put on hold
Definition at line 519 of file chan_sip.c.
char default_mohsuggest[MAX_MUSICCLASS] [static] |
Global setting for moh class to suggest when putting a bridged channel on hold
Definition at line 520 of file chan_sip.c.
char default_notifymime[AST_MAX_EXTENSION] [static] |
Definition at line 516 of file chan_sip.c.
struct ast_codec_pref default_prefs [static] |
Default codec prefs
Definition at line 523 of file chan_sip.c.
Referenced by build_device(), build_user(), reload_config(), set_peer_defaults(), sip_alloc(), sip_show_settings(), and temp_peer().
int default_qualify [static] |
Default Qualify= setting
Definition at line 517 of file chan_sip.c.
char default_subscribecontext[AST_MAX_CONTEXT] [static] |
Definition at line 512 of file chan_sip.c.
char default_vmexten[AST_MAX_EXTENSION] [static] |
Definition at line 518 of file chan_sip.c.
char* descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static] |
Definition at line 17004 of file chan_sip.c.
char* descrip_sipaddheader [static] |
Definition at line 17010 of file chan_sip.c.
int dumphistory [static] |
Dump history to verbose before destroying SIP dialog
Definition at line 550 of file chan_sip.c.
int expiry = DEFAULT_EXPIRY [static] |
Definition at line 186 of file chan_sip.c.
time_t externexpire = 0 [static] |
Expiration counter for re-resolving external host name in dynamic DNS
Definition at line 1185 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and reload_config().
char externhost[MAXHOSTNAMELEN] [static] |
External host name (possibly with dynamic DNS and DHCP
Definition at line 1184 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and reload_config().
struct sockaddr_in externip [static] |
External IP address if we are behind NAT
Definition at line 1183 of file chan_sip.c.
int externrefresh = 10 [static] |
Definition at line 1186 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), and reload_config().
int global_allowguest [static] |
allow unauthenticated users/peers to connect?
Definition at line 541 of file chan_sip.c.
int global_allowsubscribe [static] |
Flag for disabling ALL subscriptions, this is FALSE only if all peers are FALSE the global setting is in globals_flags[1]
Definition at line 542 of file chan_sip.c.
enum transfermodes global_allowtransfer [static] |
SIP Refer restriction scheme
Definition at line 558 of file chan_sip.c.
int global_alwaysauthreject [static] |
Send 401 Unauthorized for all failing requests
Definition at line 531 of file chan_sip.c.
int global_autoframing [static] |
Turn autoframing on or off.
Definition at line 557 of file chan_sip.c.
int global_callevents [static] |
Whether we send manager events or not
Definition at line 555 of file chan_sip.c.
int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 [static] |
int global_directrtpsetup [static] |
Enable support for Direct RTP setup (no re-invites)
Definition at line 526 of file chan_sip.c.
struct ast_flags global_flags[2] = {{0}} [static] |
global SIP_ flags
Definition at line 573 of file chan_sip.c.
Referenced by build_peer(), build_radius_record(), build_user(), destroy_association(), get_destination(), load_module(), realtime_update_peer(), reload_config(), set_peer_defaults(), sip_alloc(), sip_do_debug(), sip_do_debug_deprecated(), sip_do_debug_ip(), sip_do_debug_peer(), sip_no_debug(), sip_no_debug_deprecated(), sip_show_settings(), transmit_response_using_temp(), and update_peer().
struct ast_jb_conf global_jbconf [static] |
Definition at line 220 of file chan_sip.c.
int global_limitonpeers [static] |
Match call limit on peers only
Definition at line 527 of file chan_sip.c.
int global_matchexterniplocally [static] |
Match externip/externhost setting against localnet setting
Definition at line 560 of file chan_sip.c.
int global_mwitime [static] |
Time between MWI checks for peers
Definition at line 544 of file chan_sip.c.
int global_notifyhold [static] |
Send notifications on hold
Definition at line 530 of file chan_sip.c.
int global_notifyringing [static] |
Send notifications on ringing
Definition at line 529 of file chan_sip.c.
char global_realm[MAXHOSTNAMELEN] [static] |
Default realm
Definition at line 551 of file chan_sip.c.
int global_reg_timeout [static] |
Definition at line 539 of file chan_sip.c.
int global_regattempts_max [static] |
Registration attempts before giving up
Definition at line 540 of file chan_sip.c.
char global_regcontext[AST_MAX_CONTEXT] [static] |
Context for auto-extensions
Definition at line 552 of file chan_sip.c.
int global_relaxdtmf [static] |
Relax DTMF
Definition at line 535 of file chan_sip.c.
int global_rtautoclear [static] |
Definition at line 528 of file chan_sip.c.
int global_rtpholdtimeout [static] |
Definition at line 537 of file chan_sip.c.
int global_rtpkeepalive [static] |
Send RTP keepalives
Definition at line 538 of file chan_sip.c.
int global_rtptimeout [static] |
Time out call if no RTP
Definition at line 536 of file chan_sip.c.
int global_t1min [static] |
T1 roundtrip time minimum
Definition at line 556 of file chan_sip.c.
int global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 [static] |
unsigned int global_tos_audio [static] |
IP type of service for audio RTP packets
Definition at line 546 of file chan_sip.c.
unsigned int global_tos_sip [static] |
IP type of service for SIP packets
Definition at line 545 of file chan_sip.c.
unsigned int global_tos_video [static] |
IP type of service for video RTP packets
Definition at line 547 of file chan_sip.c.
char global_useragent[AST_MAX_EXTENSION] [static] |
Useragent for the SIP channel
Definition at line 553 of file chan_sip.c.
char history_usage[] [static] |
Initial value:
"Usage: sip history\n" " Enables recording of SIP dialog history for debugging purposes.\n" "Use 'sip show history' to view the history of a call number.\n"
Definition at line 11328 of file chan_sip.c.
sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe
struct io_context* io [static] |
The IO context
Definition at line 594 of file chan_sip.c.
List of local networks, on the same side of NAT as this Asterisk
Definition at line 1187 of file chan_sip.c.
Referenced by ast_sip_ouraddrfor(), reload_config(), and unload_module().
char mandescr_show_peer[] [static] |
Initial value:
"Description: Show one SIP peer with details on current status.\n" "Variables: \n" " Peer: <name> The peer name you want to check.\n" " ActionID: <id> Optional action ID for this AMI transaction.\n"
Definition at line 9962 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 9513 of file chan_sip.c.
int max_expiry = DEFAULT_MAX_EXPIRY [static] |
Maximum accepted registration time
Definition at line 184 of file chan_sip.c.
int min_expiry = DEFAULT_MIN_EXPIRY [static] |
Minimum accepted registration time
Definition at line 183 of file chan_sip.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
This is the thread for the monitor which checks for input on the channels which are not currently in use.
Definition at line 588 of file chan_sip.c.
char no_debug_usage[] [static] |
Initial value:
"Usage: sip set debug off\n" " Disables dumping of SIP packets for debugging purposes\n"
Definition at line 11320 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 11324 of file chan_sip.c.
const char notify_config[] = "sip_notify.conf" [static] |
Definition at line 223 of file chan_sip.c.
struct ast_config* notify_types [static] |
The list of manual NOTIFY types we know how to send
Definition at line 1193 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 11260 of file chan_sip.c.
int ourport [static] |
Definition at line 1190 of file chan_sip.c.
struct sockaddr_in outboundproxyip [static] |
int pedanticsipchecking [static] |
Extra checking ? Default off
Definition at line 533 of file chan_sip.c.
struct ast_peer_list peerl [static] |
The peer list: Peers and Friends.
char prune_realtime_usage[] [static] |
Initial value:
"Usage: sip prune realtime [peer|user] [<name>|all|like <pattern>]\n" " Prunes object(s) from the cache.\n" " Optional regular expression pattern is used to filter the objects.\n"
Definition at line 11302 of file chan_sip.c.
int recordhistory [static] |
Record SIP history. Off by default
Definition at line 549 of file chan_sip.c.
struct c_referstatusstring referstatusstrings[] [static] |
Referenced by referstatus2str().
struct ast_register_list regl [static] |
The register list: Other SIP proxys we register with and place calls to.
Referenced by load_module(), sip_do_reload(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module().
int regobjs = 0 [static] |
Registry objects
Definition at line 571 of file chan_sip.c.
int rpeerobjs = 0 [static] |
Realtime peers
Definition at line 569 of file chan_sip.c.
int ruserobjs = 0 [static] |
Realtime users
Definition at line 567 of file chan_sip.c.
struct sched_context* sched [static] |
The scheduling context
Definition at line 593 of file chan_sip.c.
char show_channel_usage[] [static] |
Initial value:
"Usage: sip show channel <channel>\n" " Provides detailed status on a given SIP channel.\n"
Definition at line 11284 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 11280 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 11255 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 11288 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 11275 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 11341 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 11297 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 11292 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 11307 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 11345 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 11337 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 11270 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 11265 of file chan_sip.c.
struct ast_custom_function sip_header_function [static] |
struct cfsip_methods sip_methods[] [static] |
XXX Note that sip_methods[i].id == i must hold or the code breaks
Referenced by __sip_ack(), __sip_autodestruct(), __sip_destroy(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), check_auth(), do_proxy_auth(), find_sip_method(), get_destination(), handle_request(), handle_request_subscribe(), handle_response(), init_req(), initreqprep(), method_match(), reqprep(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_scheddestroy(), and transmit_register().
struct cfsip_options sip_options[] [static] |
List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly.
Referenced by _sip_show_peer(), parse_sip_options(), and sip_show_channel().
char sip_reload_usage[] [static] |
Initial value:
"Usage: sip reload\n" " Reloads SIP configuration from sip.conf\n"
Definition at line 11333 of file chan_sip.c.
int sip_reloading = FALSE [static] |
Flag for avoiding multiple reloads at the same time
Definition at line 590 of file chan_sip.c.
enum channelreloadreason sip_reloadreason [static] |
Reason for last reload/load of configuration
Definition at line 591 of file chan_sip.c.
struct ast_rtp_protocol sip_rtp [static] |
Interface structure with callbacks used to connect to RTP module.
Definition at line 1588 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 1531 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 1557 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 1597 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 11582 of file chan_sip.c.
Referenced by load_module(), and unload_module().
Structure to declare a dialplan function: SIPPEER.
Definition at line 11502 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 1181 of file chan_sip.c.
Referenced by __sip_xmit(), do_monitor(), reg_source_db(), sipsock_read(), and unload_module().
int* sipsock_read_id [static] |
ID of IO entry for sipsock FD
Definition at line 595 of file chan_sip.c.
int speerobjs = 0 [static] |
Statis peers
Definition at line 568 of file chan_sip.c.
int srvlookup [static] |
SRV Lookup on or off. Default is off, RFC behavior is on
Definition at line 532 of file chan_sip.c.
struct cfsubscription_types subscription_types[] [static] |
Referenced by find_subscription_type(), and subscription_type2str().
int suserobjs = 0 [static] |
Static users
Definition at line 566 of file chan_sip.c.
char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static] |
Definition at line 17003 of file chan_sip.c.
char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static] |
Definition at line 17008 of file chan_sip.c.
struct ast_user_list userl [static] |
The user list: Users and friends.
1.5.1